#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; }