Search across packages, versions, files, declarations, and comments. Use multiple terms to narrow results (AND), and add @vertex, @fragment, or @compute to filter by shader stage.
1#import bevy_pbr::{
2 atmosphere::{
3 bindings::settings,
4 functions::{
5 sample_density_lut, sample_local_inscattering, uv_to_ray_direction, get_view_position,
6 MIDPOINT_RATIO, MIN_EXTINCTION, ABSORPTION_DENSITY, SCATTERING_DENSITY,
7 },
8 }
9}
12@group(0) @binding(13) var aerial_view_lut_out: texture_storage_3d<rgba16float, write>;
14@compute
15@workgroup_size(16, 16, 1)
16fn main(@builtin(global_invocation_id) idx: vec3<u32>) {
17 if any(idx.xy > settings.aerial_view_lut_size.xy) { return; }
19 let uv = (vec2<f32>(idx.xy) + 0.5) / vec2<f32>(settings.aerial_view_lut_size.xy);
20 let ray_dir = uv_to_ray_direction(uv);
21 let world_pos = get_view_position();
23 let r = length(world_pos);
24 let t_max = settings.aerial_view_lut_max_distance;
26 var prev_t = 0.0;
27 var total_inscattering = vec3(0.0);
28 var throughput = vec3(1.0);
30 for (var slice_i: u32 = 0; slice_i < settings.aerial_view_lut_size.z; slice_i++) {
31 for (var step_i: u32 = 0; step_i < settings.aerial_view_lut_samples; step_i++) {
32 let t_i = t_max * (f32(slice_i) + ((f32(step_i) + MIDPOINT_RATIO) / f32(settings.aerial_view_lut_samples))) / f32(settings.aerial_view_lut_size.z);
33 let dt = (t_i - prev_t);
34 prev_t = t_i;
36 let sample_pos = world_pos + ray_dir * t_i;
37 let local_r = length(sample_pos);
38 let local_up = normalize(sample_pos);
40 let absorption = sample_density_lut(local_r, ABSORPTION_DENSITY);
41 let scattering = sample_density_lut(local_r, SCATTERING_DENSITY);
42 let extinction = absorption + scattering;
44 let sample_optical_depth = extinction * dt;
45 let sample_transmittance = exp(-sample_optical_depth);
47 // evaluate one segment of the integral
48 var inscattering = sample_local_inscattering(scattering, ray_dir, sample_pos);
50 // Analytical integration of the single scattering term in the radiance transfer equation
51 let s_int = (inscattering - inscattering * sample_transmittance) / max(extinction, MIN_EXTINCTION);
52 total_inscattering += throughput * s_int;
54 throughput *= sample_transmittance;
55 if all(throughput < vec3(0.001)) {
56 break;
57 }
58 }
60 // Store in log space to allow linear interpolation of exponential values between slices
61 let log_inscattering = log(max(total_inscattering, vec3(1e-6)));
62 textureStore(aerial_view_lut_out, vec3(vec2<u32>(idx.xy), slice_i), vec4(log_inscattering, 0.0));
63 }
Contents