61 lines
1.9 KiB
Text
61 lines
1.9 KiB
Text
|
#version 330 core
|
||
|
|
||
|
uniform sampler2D transmittance_tex;
|
||
|
|
||
|
uniform vec3 fg_CameraPositionCart;
|
||
|
uniform vec3 fg_SunDirectionWorld;
|
||
|
|
||
|
const int AERIAL_PERSPECTIVE_ENVMAP_STEPS = 4;
|
||
|
|
||
|
// atmos.glsl
|
||
|
float get_earth_radius();
|
||
|
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);
|
||
|
// atmos_spectral.glsl
|
||
|
vec4 get_sun_spectral_irradiance();
|
||
|
vec3 linear_srgb_from_spectral_samples(vec4 L);
|
||
|
|
||
|
vec4 get_aerial_perspective(vec3 pos)
|
||
|
{
|
||
|
vec3 ray_origin = fg_CameraPositionCart;
|
||
|
vec3 ray_end = pos;
|
||
|
|
||
|
// Make sure both ray ends are above the ground.
|
||
|
// We also apply a small bias to the ray end to prevent both points from
|
||
|
// being at the exact same place due to floating point precision.
|
||
|
float radius = get_earth_radius();
|
||
|
ray_origin += max(0.0, radius - length(ray_origin));
|
||
|
ray_end += max(0.0, radius - length(ray_end)) + 1.0;
|
||
|
|
||
|
vec3 ray_dir = ray_end - ray_origin;
|
||
|
float t_d = length(ray_dir);
|
||
|
ray_dir /= t_d;
|
||
|
|
||
|
float t_max = get_ray_end(ray_origin, ray_dir, t_d);
|
||
|
|
||
|
vec4 transmittance;
|
||
|
vec4 L = compute_inscattering(ray_origin,
|
||
|
ray_dir,
|
||
|
t_max,
|
||
|
fg_SunDirectionWorld,
|
||
|
AERIAL_PERSPECTIVE_ENVMAP_STEPS,
|
||
|
transmittance_tex,
|
||
|
transmittance);
|
||
|
|
||
|
vec4 ap;
|
||
|
ap.rgb = linear_srgb_from_spectral_samples(L * get_sun_spectral_irradiance());
|
||
|
ap.a = dot(transmittance, vec4(0.25));
|
||
|
return ap;
|
||
|
}
|
||
|
|
||
|
vec3 mix_aerial_perspective(vec3 color, vec4 ap)
|
||
|
{
|
||
|
return color * ap.a + ap.rgb;
|
||
|
}
|