64 lines
1.9 KiB
GLSL
64 lines
1.9 KiB
GLSL
#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;
|
|
}
|