Open tbillington opened 1 year ago
That would tend to make ambient light the color of the sky — strongly blue, usually. Most of the time, the environmental light should be pure white, right?
It would be kind of cool to have bevy_atmosphere keep track of sun position and provide a DirectionalLight that syncs with the sky. There are two sun-position libraries on crates.io that I see, both kind of awkward, unfortunately — they are ports of a javascript library and have weird conventions like "time in milliseconds".) Plus, they've got extra steps, because there's no real reason to deal with timezones for this purpose — just assume times are UTC and the longitude is 0. Also, like the Nishita model here, the constants that represent earth should be configurable for alien environments.
I'm using this for sun position, adapted from https://stackoverflow.com/questions/8708048/position-of-the-sun-given-time-of-day-latitude-and-longitude and using it to both set the sun position in the model and its inverse for a directional light for shadows
fn sun_direction(time_of_day: f32, latitude: f32, time_of_year: f32) -> Vec3 {
// Convert time of day from [0, 1] to [-π, π]
let solar_time_rads = 2.0 * PI * (time_of_day - 0.5);
// Convert time of year from [0, 1] to [-0.41, 0.41]
// offset by 0.25 so declination is 0 at equinoxes
let declination_rads = (2.0 * PI * (time_of_year - 0.25)).sin() * 23.45f32.to_radians();
// Convert latitude from [0, 1] to [-π/2, π/2]
let latitude_rads = PI * (latitude - 0.5);
// equations adapted from https://stackoverflow.com/questions/8708048/position-of-the-sun-given-time-of-day-latitude-and-longitude
let zenith_rads = (latitude_rads.sin() * declination_rads.sin()
+ latitude_rads.cos() * declination_rads.cos() * solar_time_rads.cos())
.acos();
let mut azimuth_rads = ((latitude_rads.sin() * zenith_rads.cos() - declination_rads.sin())
/ (latitude_rads.cos() * zenith_rads.sin()))
.acos();
let elevation_rads = (declination_rads.sin() * latitude_rads.sin()
+ declination_rads.cos() * latitude_rads.cos() * solar_time_rads.cos())
.asin();
if solar_time_rads > 0.0f32 {
azimuth_rads = azimuth_rads + PI;
} else {
azimuth_rads = 3.0 * PI - azimuth_rads;
}
let x = azimuth_rads.sin() * elevation_rads.cos();
let y = elevation_rads.sin();
let z = azimuth_rads.cos() * elevation_rads.cos();
Vec3::new(x, y, z)
}
Bevy now supports
EnvironmentMapLight
as of 0.11.I don't know how possible it is, but being able to derive the environment map from from the bevy_atmosphere skybox would be handy.