// transmittance from a point in the atmosphere to its top, for the transmittance table (atmosphere_common.glsl). // one invocation per texel. run when the parameters of the atmosphere change #include #include layout(local_size_x = 8, local_size_y = 8) in; layout(binding = ATMOSPHERE_TRANSMITTANCE_UNIT, rgba16f) writeonly uniform image2D transmittance_target; const int TRANSMITTANCE_SAMPLES = 40; void main() { ivec2 texel = ivec2(gl_GlobalInvocationID.xy); if (texel.x >= int(ATMOSPHERE_TRANSMITTANCE_WIDTH) || texel.y >= int(ATMOSPHERE_TRANSMITTANCE_HEIGHT)) return; vec2 uv = (vec2(texel) + 0.5) / vec2(ATMOSPHERE_TRANSMITTANCE_WIDTH, ATMOSPHERE_TRANSMITTANCE_HEIGHT); float radius; float cosviewzenith; atmo_transmittance_params(uv, radius, cosviewzenith); vec3 origin = vec3(0.0, 0.0, radius); vec3 direction = vec3(sqrt(max(1.0 - cosviewzenith * cosviewzenith, 0.0)), 0.0, cosviewzenith); float tbottom = atmo_ray_sphere_nearest(origin, direction, atmo_bottom_radius); float ttop = atmo_ray_sphere_nearest(origin, direction, atmo_top_radius); float tmax = (tbottom > 0.0) ? ((ttop > 0.0) ? min(ttop, tbottom) : tbottom) : max(ttop, 0.0); vec3 opticaldepth = vec3(0.0); float dt = tmax / float(TRANSMITTANCE_SAMPLES); for (int s = 0; s < TRANSMITTANCE_SAMPLES; ++s) { vec3 position = origin + (float(s) + 0.5) * dt * direction; opticaldepth += atmo_sample_medium(length(position)).extinction * dt; } imageStore(transmittance_target, texel, vec4(exp(-opticaldepth), 1.0)); }