52 lines
1.8 KiB
GLSL
52 lines
1.8 KiB
GLSL
|
#version 330 core
|
||
|
|
||
|
out vec3 fragColor;
|
||
|
|
||
|
in vec2 texCoord;
|
||
|
|
||
|
uniform vec3 fg_CameraPositionCart;
|
||
|
uniform vec3 fg_CameraPositionGeod;
|
||
|
uniform vec3 fg_SunDirectionWorld;
|
||
|
|
||
|
const float PI = 3.141592653;
|
||
|
|
||
|
void calculateScattering(in vec3 rayOrigin,
|
||
|
in vec3 rayDir,
|
||
|
in float tmax,
|
||
|
in vec3 lightDir,
|
||
|
in float earthRadius,
|
||
|
out vec3 inscatter,
|
||
|
out vec3 transmittance);
|
||
|
|
||
|
void main()
|
||
|
{
|
||
|
// Always leave the sun right in the middle of the texture as the skydome
|
||
|
// model is already being rotated.
|
||
|
float sunCosTheta = dot(fg_SunDirectionWorld, normalize(fg_CameraPositionCart));
|
||
|
vec3 lightDir = vec3(-sqrt(1.0 - sunCosTheta*sunCosTheta), 0.0, sunCosTheta);
|
||
|
|
||
|
float azimuth = 2.0 * PI * texCoord.x; // [0, 2pi]
|
||
|
// Apply a non-linear transformation to the elevation to dedicate more
|
||
|
// texels to the horizon, which is where having more detail matters.
|
||
|
float l = texCoord.y * 2.0 - 1.0;
|
||
|
float elev = l*l * sign(l) * PI * 0.5; // [-pi/2, pi/2]
|
||
|
vec3 rayDir = vec3(cos(elev) * cos(azimuth), cos(elev) * sin(azimuth), sin(elev));
|
||
|
|
||
|
float cameraPosLength = length(fg_CameraPositionCart);
|
||
|
// Since FG internally uses WG84 coordinates, we use the current Earth
|
||
|
// radius under the camera, which varies with the latitude. For practical
|
||
|
// purposes we model the Earth as a perfect sphere with this radius.
|
||
|
float earthRadius = cameraPosLength - fg_CameraPositionGeod.z;
|
||
|
|
||
|
vec3 rayOrigin = vec3(0.0, 0.0, cameraPosLength);
|
||
|
|
||
|
vec3 inscatter, transmittance;
|
||
|
calculateScattering(rayOrigin,
|
||
|
rayDir,
|
||
|
9.0e8,
|
||
|
lightDir,
|
||
|
earthRadius,
|
||
|
inscatter, transmittance);
|
||
|
fragColor = inscatter;
|
||
|
}
|