-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Add bevy_light::SunDisk #20434
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add bevy_light::SunDisk #20434
Changes from 16 commits
1de0f14
be859fa
63c23f2
0a25380
f7b49ad
35e2cc2
8cf39b6
c3da658
2aa4da4
b39e4ec
592d3f1
56a1dc2
d3fe65e
62cc5c2
3e52d97
d73618d
3c37800
089f646
99a4456
dbbeff8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -240,3 +240,38 @@ pub fn update_directional_light_frusta( | |
| .collect(); | ||
| } | ||
| } | ||
|
|
||
| /// This component marks a [`DirectionalLight`] entity for changing the size and intensity of the sun disk. | ||
| #[derive(Component, Clone)] | ||
| #[require(DirectionalLight)] | ||
| pub struct SunLight { | ||
| /// The angular size (diameter) of the sun disk in radians as observed from Earth. | ||
| pub angular_size: f32, | ||
| /// Multiplier applied to the brightness of the sun disk in the sky. | ||
| /// | ||
| /// `0.0` disables the sun disk entirely while still | ||
| /// allowing the sun's radiance to scatter into the atmosphere, | ||
| /// and `1.0` renders the sun disk at its normal intensity. | ||
| pub intensity: f32, | ||
defuz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| impl SunLight { | ||
| pub const SUN: SunLight = SunLight { | ||
|
||
| // 32 arc minutes is the mean size of the sun disk when the Earth is | ||
| // exactly 1 astronomical unit from the sun. | ||
| angular_size: 0.00930842, | ||
| intensity: 1.0, | ||
| }; | ||
| } | ||
|
|
||
| impl Default for SunLight { | ||
| fn default() -> Self { | ||
| Self::SUN | ||
| } | ||
| } | ||
|
|
||
| impl Default for &SunLight { | ||
| fn default() -> Self { | ||
| &SunLight::SUN | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,7 +36,6 @@ | |
|
|
||
|
|
||
| // CONSTANTS | ||
|
|
||
| const FRAC_PI: f32 = 0.3183098862; // 1 / π | ||
| const FRAC_2_PI: f32 = 0.15915494309; // 1 / (2π) | ||
| const FRAC_3_16_PI: f32 = 0.0596831036594607509; // 3 / (16π) | ||
|
|
@@ -275,8 +274,6 @@ fn sample_local_inscattering(local_atmosphere: AtmosphereSample, ray_dir: vec3<f | |
| return inscattering; | ||
| } | ||
|
|
||
| const SUN_ANGULAR_SIZE: f32 = 0.0174533; // angular diameter of sun in radians | ||
|
|
||
| fn sample_sun_radiance(ray_dir_ws: vec3<f32>) -> vec3<f32> { | ||
| let r = view_radius(); | ||
| let mu_view = ray_dir_ws.y; | ||
|
|
@@ -285,11 +282,15 @@ fn sample_sun_radiance(ray_dir_ws: vec3<f32>) -> vec3<f32> { | |
| for (var light_i: u32 = 0u; light_i < lights.n_directional_lights; light_i++) { | ||
| let light = &lights.directional_lights[light_i]; | ||
| let neg_LdotV = dot((*light).direction_to_light, ray_dir_ws); | ||
| let angle_to_sun = fast_acos(neg_LdotV); | ||
| let pixel_size = fwidth(angle_to_sun); | ||
| let factor = smoothstep(0.0, -pixel_size * ROOT_2, angle_to_sun - SUN_ANGULAR_SIZE * 0.5); | ||
| let sun_solid_angle = (SUN_ANGULAR_SIZE * SUN_ANGULAR_SIZE) * 4.0 * FRAC_PI; | ||
| sun_radiance += ((*light).color.rgb / sun_solid_angle) * factor * shadow_factor; | ||
| let angle_to_sun = fast_acos(clamp(neg_LdotV, -1.0, 1.0)); | ||
| let w = max(0.5 * fwidth(angle_to_sun), 1e-6); | ||
| let sun_angular_size = (*light).angular_size; | ||
| let sun_intensity = (*light).intensity; | ||
| if sun_angular_size > 0.0 && sun_intensity > 0.0 { | ||
| let factor = 1 - smoothstep(sun_angular_size * 0.5 - w, sun_angular_size * 0.5 + w, angle_to_sun); | ||
| let sun_solid_angle = (sun_angular_size * sun_angular_size) * 0.25 * PI; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the same expression as before, even though the PR description/comment above suggests otherwise. 0.25 = 1 / 4
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's precisely reciprocal, no? 4/pi vs pi/4. :) |
||
| sun_radiance += ((*light).color.rgb / sun_solid_angle) * sun_intensity * factor * shadow_factor; | ||
| } | ||
| } | ||
| return sun_radiance; | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.