4 sun_position: vec3<f32>, 7 atmosphere_radius: f32, 8 rayleigh_coefficient: vec3<f32>, 9 rayleigh_scale_height: f32, 11 mie_scale_height: f32, 15const PI: f32 = 3.141592653589793; 16const ISTEPS: u32 = 16u; 17const JSTEPS: u32 = 8u; 19fn rsi(rd: vec3<f32>, r0: vec3<f32>, sr: f32) -> vec2<f32> { 24 let b = 2.0 * dot(rd, r0); 25 let c = dot(r0, r0) - (sr * sr); 26 let d = (b * b) - (4.0 * a * c); 29 return vec2<f32>(1e5, -1e5); 32 (-b - sqrt(d)) / (2.0 * a), 33 (-b + sqrt(d)) / (2.0 * a) 38fn render_nishita(r_full: vec3<f32>, r0: vec3<f32>, p_sun_full: vec3<f32>, i_sun: f32, r_planet: f32, r_atmos: f32, k_rlh: vec3<f32>, k_mie: f32, sh_rlh: f32, sh_mie: f32, g: f32) -> vec3<f32> { 40 let r = normalize(r_full); 41 let p_sun = normalize(p_sun_full); 44 var p = rsi(r, r0, r_atmos); 45 if p.x > p.y { return vec3<f32>(0f); } 46 p.y = min(p.y, rsi(r, r0, r_planet).x); 47 let i_step_size = (p.y - p.x) / f32(ISTEPS); 53 var total_rlh = vec3<f32>(0f); 54 var total_mie = vec3<f32>(0f); 61 let mu = dot(r, p_sun); 64 let p_rlh = 3.0 / (16.0 * PI) * (1.0 + mumu); 65 let p_mie = 3.0 / (8.0 * PI) * ((1.0 - gg) * (mumu + 1.0)) / (pow(1.0 + gg - 2.0 * mu * g, 1.5) * (2.0 + gg)); 68 for (var i = 0u; i < ISTEPS; i++) { 70 let i_pos = r0 + r * (i_depth + i_step_size * 0.5); 73 let i_height = length(i_pos) - r_planet; 76 let od_step_rlh = exp(-i_height / sh_rlh) * i_step_size; 77 let od_step_mie = exp(-i_height / sh_mie) * i_step_size; 80 i_od_rlh += od_step_rlh; 81 i_od_mie += od_step_mie; 84 let j_step_size = rsi(p_sun, i_pos, r_atmos).y / f32(JSTEPS); 94 for (var j = 0u; j < JSTEPS; j++) { 97 let j_pos = i_pos + p_sun * (j_depth + j_step_size * 0.5); 100 let j_height = length(j_pos) - r_planet; 103 j_od_rlh += exp(-j_height / sh_rlh) * j_step_size; 104 j_od_mie += exp(-j_height / sh_mie) * j_step_size; 107 j_depth += j_step_size; 111 let attn = exp(-(k_mie * (i_od_mie + j_od_mie) + k_rlh * (i_od_rlh + j_od_rlh))); 114 total_rlh += od_step_rlh * attn; 115 total_mie += od_step_mie * attn; 118 i_depth += i_step_size; 122 return i_sun * (p_rlh * k_rlh * total_rlh + p_mie * k_mie * total_mie); 126var<uniform> nishita: Nishita; 129var image: texture_storage_2d_array<rgba16float, write>; 131@compute @workgroup_size(8, 8, 1) 132fn main(@builtin(global_invocation_id) invocation_id: vec3<u32>, @builtin(num_workgroups) num_workgroups: vec3<u32>) { 133 let size = textureDimensions(image).x; 134 let scale = f32(size) / 2f; 136 let dir = vec2<f32>((f32(invocation_id.x) / scale) - 1f, (f32(invocation_id.y) / scale) - 1f); 140 switch invocation_id.z { 142 ray = vec3<f32>(1f, -dir.y, -dir.x); 145 ray = vec3<f32>(-1f, -dir.y, dir.x); 148 ray = vec3<f32>(dir.x, 1f, dir.y); 151 ray = vec3<f32>(dir.x, -1f, -dir.y); 154 ray = vec3<f32>(dir.x, -dir.y, 1f); 157 ray = vec3<f32>(-dir.x, -dir.y, -1f); 161 let render = render_nishita( 164 nishita.sun_position, 165 nishita.sun_intensity, 166 nishita.planet_radius, 167 nishita.atmosphere_radius, 168 nishita.rayleigh_coefficient, 169 nishita.mie_coefficient, 170 nishita.rayleigh_scale_height, 171 nishita.mie_scale_height, 172 nishita.mie_direction, 177 vec2<i32>(invocation_id.xy), 178 i32(invocation_id.z), 179 vec4<f32>(render, 1.0)