bevy/crates/bevy_pbr/src/atmosphere/render_sky.wgsl
Emerson Coskey 81a25bb0c7
Procedural atmospheric scattering (#16314)
Implement procedural atmospheric scattering from [Sebastien Hillaire's
2020 paper](https://sebh.github.io/publications/egsr2020.pdf). This
approach should scale well even down to mobile hardware, and is
physically accurate.

## Co-author: @mate-h 

He helped massively with getting this over the finish line, ensuring
everything was physically correct, correcting several places where I had
misunderstood or misapplied the paper, and improving the performance in
several places as well. Thanks!

## Credits

@aevyrie: helped find numerous bugs and improve the example to best show
off this feature :)

Built off of @mtsr's original branch, which handled the transmittance
lut (arguably the most important part)

## Showcase: 


![sunset](https://github.com/user-attachments/assets/2eee1f38-f66d-4772-bb72-163e13c719d8)

![twilight](https://github.com/user-attachments/assets/f7d358b6-898d-4df7-becc-188cd753102d)


## For followup

- Integrate with pcwalton's volumetrics code
- refactor/reorganize for better integration with other effects
- have atmosphere transmittance affect directional lights
- add support for generating skybox/environment map

---------

Co-authored-by: Emerson Coskey <56370779+EmersonCoskey@users.noreply.github.com>
Co-authored-by: atlv <email@atlasdostal.com>
Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
Co-authored-by: Emerson Coskey <coskey@emerlabs.net>
Co-authored-by: Máté Homolya <mate.homolya@gmail.com>
2025-01-23 22:52:46 +00:00

40 lines
1.4 KiB
WebGPU Shading Language

#import bevy_pbr::atmosphere::{
types::{Atmosphere, AtmosphereSettings},
bindings::{atmosphere, view, atmosphere_transforms},
functions::{
sample_transmittance_lut, sample_sky_view_lut,
direction_world_to_atmosphere, uv_to_ray_direction,
uv_to_ndc, sample_aerial_view_lut, view_radius,
sample_sun_illuminance,
},
};
#import bevy_render::view::View;
#import bevy_core_pipeline::fullscreen_vertex_shader::FullscreenVertexOutput
#ifdef MULTISAMPLED
@group(0) @binding(13) var depth_texture: texture_depth_multisampled_2d;
#else
@group(0) @binding(13) var depth_texture: texture_depth_2d;
#endif
@fragment
fn main(in: FullscreenVertexOutput) -> @location(0) vec4<f32> {
let depth = textureLoad(depth_texture, vec2<i32>(in.position.xy), 0);
if depth == 0.0 {
let ray_dir_ws = uv_to_ray_direction(in.uv);
let ray_dir_as = direction_world_to_atmosphere(ray_dir_ws.xyz);
let r = view_radius();
let mu = ray_dir_ws.y;
let transmittance = sample_transmittance_lut(r, mu);
let inscattering = sample_sky_view_lut(r, ray_dir_as);
let sun_illuminance = sample_sun_illuminance(ray_dir_ws.xyz, transmittance);
return vec4(inscattering + sun_illuminance, (transmittance.r + transmittance.g + transmittance.b) / 3.0);
} else {
return sample_aerial_view_lut(in.uv, depth);
}
}