1
0
Fork 0

HDR: Fix aerial perspective banding

This commit is contained in:
Fernando García Liñán 2023-04-13 05:57:01 +02:00
parent f53a170539
commit e77e5bad9c
5 changed files with 40 additions and 31 deletions

View file

@ -112,7 +112,7 @@
<name>aerial-perspective</name>
<type>2d</type>
<width>1024</width>
<height>32</height>
<height>64</height>
<format>rgba16f</format>
<min-filter>linear</min-filter>
<mag-filter>linear</mag-filter>

View file

@ -8,9 +8,9 @@ uniform float fg_CameraDistanceToEarthCenter;
uniform float fg_SunZenithCosTheta;
uniform float fg_EarthRadius;
const float AP_SLICE_COUNT = 32.0;
const float AP_SLICE_COUNT = 16.0;
const float AP_MAX_DEPTH = 128000.0;
const float AP_SLICE_WIDTH_PIXELS = 32.0;
const float AP_SLICE_WIDTH_PIXELS = 64.0;
const float AP_SLICE_SIZE = 1.0 / AP_SLICE_COUNT;
const float AP_TEXEL_WIDTH = 1.0 / (AP_SLICE_COUNT * AP_SLICE_WIDTH_PIXELS);

View file

@ -216,27 +216,14 @@ void get_atmosphere_collision_coefficients(in float h,
}
/*
* Compute the in-scattering integral of the volume rendering equation (VRE)
*
* The integral is solved numerically by ray marching. The final in-scattering
* returned by this function is a 4D vector of the spectral radiance sampled for
* the 4 wavelengths at the top of this file. To obtain an RGB triplet, the
* spectral radiance must be multiplied by the spectral irradiance of the Sun
* and converted to sRGB.
* Any given ray inside the atmospheric medium can end in one of 3 places:
* 1. The Earth's surface.
* 2. Outer space. We define the boundary between space and the atmosphere
* at the Kármán line (100 km above sea level).
* 3. Any object within the atmosphere.
*/
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)
float get_ray_end(vec3 ray_origin, vec3 ray_dir, float t_max)
{
// Any given ray inside the atmospheric medium can end in one of 3 places:
// 1. The Earth's surface.
// 2. Outer space. We define the boundary between space and the atmosphere
// at the Kármán line.
// 3. Any object within the atmosphere.
float ray_altitude = length(ray_origin);
// Handle the camera being underground
float earth_radius = min(ray_altitude, get_earth_radius());
@ -255,19 +242,34 @@ vec4 compute_inscattering(in vec3 ray_origin,
} else {
// We are in outer space
// XXX: For now this is a flight simulator, not a space simulator
transmittance = vec4(1.0);
return vec4(0.0);
t_d = -1.0;
}
return min(t_d, t_max);
}
// Clip by the maximum distance
t_d = min(t_d, t_max);
/*
* Compute the in-scattering integral of the volume rendering equation (VRE)
*
* The integral is solved numerically by ray marching. The final in-scattering
* returned by this function is a 4D vector of the spectral radiance sampled for
* the 4 wavelengths at the top of this file. To obtain an RGB triplet, the
* spectral radiance must be multiplied by the spectral irradiance of the Sun
* and converted to sRGB.
*/
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)
{
float cos_theta = dot(-ray_dir, sun_dir);
float molecular_phase = molecular_phase_function(cos_theta);
float aerosol_phase = aerosol_phase_function(cos_theta);
float dt = t_d / float(steps);
float dt = t_max / float(steps);
vec4 L_inscattering = vec4(0.0);
transmittance = vec4(1.0);

View file

@ -21,10 +21,10 @@ uniform mat4 fg_ViewMatrixInverse;
uniform vec3 fg_CameraPositionCart;
uniform vec3 fg_SunDirectionWorld;
const float AP_SLICE_COUNT = 32.0;
const float AP_SLICE_COUNT = 16.0;
const float AP_MAX_DEPTH = 128000.0;
const int AERIAL_PERSPECTIVE_STEPS = 20;
const int AERIAL_PERSPECTIVE_STEPS = 10;
// pos_from_depth.glsl
vec3 get_view_space_from_depth(vec2 uv, float depth);

View file

@ -15,6 +15,7 @@ const int SKY_STEPS = 32;
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,
@ -45,10 +46,16 @@ void main()
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,
1e7,
t_max,
sun_dir,
SKY_STEPS,
transmittance_lut,