2023-04-07 06:17:37 +00:00
|
|
|
/*
|
|
|
|
* Render the aerial perspective LUT, similar to
|
|
|
|
* "A Scalable and Production Ready Sky and Atmosphere Rendering Technique"
|
|
|
|
* by Sébastien Hillaire (2020).
|
|
|
|
*
|
|
|
|
* Unlike the paper, we are using a tiled 2D texture instead of a true 3D
|
|
|
|
* texture. For some reason the overhead of rendering to a texture many times
|
|
|
|
* (the depth of the 3D texture) seems to be too high, probably because OSG is
|
|
|
|
* not sharing state between those passes.
|
|
|
|
*/
|
2021-07-28 07:40:04 +00:00
|
|
|
|
2021-07-26 10:10:58 +00:00
|
|
|
#version 330 core
|
|
|
|
|
2023-04-07 06:17:37 +00:00
|
|
|
layout(location = 0) out vec4 fragColor;
|
2021-07-26 10:10:58 +00:00
|
|
|
|
2023-04-07 06:17:37 +00:00
|
|
|
in vec2 texcoord;
|
2021-07-26 10:10:58 +00:00
|
|
|
|
2021-08-19 10:50:01 +00:00
|
|
|
uniform sampler2D transmittance_lut;
|
|
|
|
|
2021-07-26 10:10:58 +00:00
|
|
|
uniform mat4 fg_ViewMatrixInverse;
|
|
|
|
uniform vec3 fg_CameraPositionCart;
|
|
|
|
uniform vec3 fg_SunDirectionWorld;
|
2021-07-28 07:40:04 +00:00
|
|
|
|
2023-02-19 15:47:55 +00:00
|
|
|
const float AP_SLICE_COUNT = 32.0;
|
|
|
|
const float AP_MAX_DEPTH = 128000.0;
|
|
|
|
const int AERIAL_PERSPECTIVE_STEPS = 20;
|
2021-07-26 10:10:58 +00:00
|
|
|
|
2023-04-07 06:17:37 +00:00
|
|
|
// pos_from_depth.glsl
|
|
|
|
vec3 get_view_space_from_depth(vec2 uv, float depth);
|
|
|
|
// atmos.glsl
|
2023-02-19 15:47:55 +00:00
|
|
|
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);
|
2023-04-07 06:17:37 +00:00
|
|
|
// atmos_spectral.glsl
|
|
|
|
vec4 get_sun_spectral_irradiance();
|
|
|
|
vec3 linear_srgb_from_spectral_samples(vec4 L);
|
2021-07-26 10:10:58 +00:00
|
|
|
|
|
|
|
void main()
|
|
|
|
{
|
2023-02-19 15:47:55 +00:00
|
|
|
// Account for the depth slice we are currently in. Depth goes from 0 to
|
|
|
|
// DEPTH_RANGE in a squared distribution. The first slice is not 0 since
|
|
|
|
// that would waste a slice.
|
2023-04-07 06:17:37 +00:00
|
|
|
float x = texcoord.x * AP_SLICE_COUNT;
|
2023-02-19 15:47:55 +00:00
|
|
|
float slice = ceil(x);
|
|
|
|
float w = slice / AP_SLICE_COUNT; // [0,1]
|
|
|
|
float depth = w*w * AP_MAX_DEPTH;
|
|
|
|
|
2023-04-07 06:17:37 +00:00
|
|
|
vec2 coord = vec2(fract(x), texcoord.y);
|
2023-02-19 15:47:55 +00:00
|
|
|
|
2023-04-07 06:17:37 +00:00
|
|
|
vec3 frag_pos = get_view_space_from_depth(coord, 1.0);
|
2023-02-19 15:47:55 +00:00
|
|
|
vec3 ray_dir = vec4(fg_ViewMatrixInverse * vec4(normalize(frag_pos), 0.0)).xyz;
|
|
|
|
|
|
|
|
vec4 transmittance;
|
|
|
|
vec4 L = compute_inscattering(fg_CameraPositionCart,
|
|
|
|
ray_dir,
|
|
|
|
depth,
|
|
|
|
fg_SunDirectionWorld,
|
|
|
|
AERIAL_PERSPECTIVE_STEPS,
|
|
|
|
transmittance_lut,
|
|
|
|
transmittance);
|
|
|
|
// In-scattering
|
2023-04-07 06:17:37 +00:00
|
|
|
fragColor.rgb = linear_srgb_from_spectral_samples(
|
|
|
|
L * get_sun_spectral_irradiance());
|
2023-02-19 15:47:55 +00:00
|
|
|
// Transmittance
|
|
|
|
fragColor.a = dot(transmittance, vec4(0.25));
|
2021-07-26 10:10:58 +00:00
|
|
|
}
|