#version 330 core layout(location = 0) out vec4 fragColor; in vec2 texcoord; uniform sampler2D transmittance_lut; uniform float fg_SunZenithCosTheta; uniform float fg_CameraDistanceToEarthCenter; const int SKY_STEPS = 32; // math.glsl float M_2PI(); float M_PI_2(); // atmos.glsl float get_ray_end(vec3 ray_origin, vec3 ray_dir, float t_max); vec4 compute_inscattering(in vec3 ray_origin, in vec3 ray_dir, in float t_max, in vec3 sun_dir, in int steps, in sampler2D transmittance_lut, out vec4 transmittance); void main() { // Always leave the Sun right in the middle of the sky texture. // The skydome model implemented in SimGear already takes care of rotating // the Sun for us. vec3 sun_dir = vec3( -sqrt(1.0 - fg_SunZenithCosTheta*fg_SunZenithCosTheta), 0.0, fg_SunZenithCosTheta); float azimuth = M_2PI() * texcoord.x; // [0, 2pi] // Apply a non-linear transformation to the elevation to dedicate more // texels to the horizon, where having more detail matters. float l = texcoord.y * 2.0 - 1.0; float elev = l*l * sign(l) * M_PI_2(); // [-pi/2, pi/2] vec3 ray_dir = vec3(cos(elev) * cos(azimuth), cos(elev) * sin(azimuth), sin(elev)); vec3 ray_origin = vec3(0.0, 0.0, fg_CameraDistanceToEarthCenter); float t_max = get_ray_end(ray_origin, ray_dir, 1e7); if (t_max < 0.0) { fragColor = vec4(0.0); return; } vec4 transmittance; vec4 L = compute_inscattering(ray_origin, ray_dir, t_max, sun_dir, SKY_STEPS, transmittance_lut, transmittance); fragColor = L; }