HDR: Attempt to fix aerial perspective NaNs
This commit is contained in:
parent
7b5255eac4
commit
161ff44981
5 changed files with 32 additions and 49 deletions
|
@ -26,18 +26,9 @@ 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);
|
||||
float t_max = length(ray_dir);
|
||||
ray_dir = normalize(ray_dir);
|
||||
|
||||
vec4 transmittance;
|
||||
vec4 L = compute_inscattering(ray_origin,
|
||||
|
|
|
@ -237,24 +237,28 @@ void get_atmosphere_collision_coefficients(in float h,
|
|||
float get_ray_end(vec3 ray_origin, vec3 ray_dir, float t_max)
|
||||
{
|
||||
float ray_altitude = length(ray_origin);
|
||||
// Handle the camera being underground
|
||||
float earth_radius = min(ray_altitude, get_earth_radius());
|
||||
float atmos_dist = ray_sphere_intersection(ray_origin, ray_dir, get_atmosphere_radius());
|
||||
float ground_dist = ray_sphere_intersection(ray_origin, ray_dir, earth_radius + 1e-3);
|
||||
float t_d;
|
||||
if (ray_altitude < get_atmosphere_radius()) {
|
||||
// We are inside the atmosphere
|
||||
if (ground_dist < 0.0) {
|
||||
// No ground collision, use the distance to the outer atmosphere
|
||||
t_d = atmos_dist;
|
||||
// If the ray origin is underground, put the ground a bit below it
|
||||
float earth_radius = min(get_earth_radius(), ray_altitude - 1.0);
|
||||
|
||||
if (ray_altitude >= get_atmosphere_radius()) {
|
||||
// We are in outer space, move the ray origin to the atmospheric boundary
|
||||
// XXX: No atmosphere rendering from space yet
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
float t_atmos = ray_sphere_intersection(ray_origin, ray_dir, get_atmosphere_radius());
|
||||
float t_ground = ray_sphere_intersection(ray_origin, ray_dir, earth_radius);
|
||||
float t_d = 0.0;
|
||||
if (t_ground < 0.0) {
|
||||
if (t_atmos < 0.0) {
|
||||
t_d = -1.0;
|
||||
} else {
|
||||
// We have a collision with the ground, use the distance to it
|
||||
t_d = ground_dist;
|
||||
t_d = t_atmos;
|
||||
}
|
||||
} else {
|
||||
// We are in outer space
|
||||
// XXX: For now this is a flight simulator, not a space simulator
|
||||
t_d = -1.0;
|
||||
if (t_atmos > 0.0) {
|
||||
t_d = min(t_atmos, t_ground);
|
||||
}
|
||||
}
|
||||
return min(t_d, t_max);
|
||||
}
|
||||
|
@ -276,13 +280,19 @@ vec4 compute_inscattering(in vec3 ray_origin,
|
|||
in sampler2D transmittance_lut,
|
||||
out vec4 transmittance)
|
||||
{
|
||||
float t_d = get_ray_end(ray_origin, ray_dir, t_max);
|
||||
if (t_d < 1e-3) {
|
||||
// No intersection with the atmosphere or the ray origin and end points
|
||||
// are too close too each other. In both cases there is no inscattering.
|
||||
return vec4(0.0);
|
||||
}
|
||||
float dt = t_d / float(steps);
|
||||
|
||||
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_max / float(steps);
|
||||
|
||||
vec4 L_inscattering = vec4(0.0);
|
||||
transmittance = vec4(1.0);
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ const float AP_SLICE_COUNT = 32.0;
|
|||
const float AP_MAX_DEPTH = 128000.0;
|
||||
|
||||
const int AERIAL_PERSPECTIVE_STEPS = 10;
|
||||
const float RADIUS_OFFSET = 10.0;
|
||||
|
||||
// pos_from_depth.glsl
|
||||
vec3 get_view_space_from_depth(vec2 uv, float depth);
|
||||
|
@ -60,21 +59,10 @@ void main()
|
|||
|
||||
vec3 ray_origin = fg_CameraPositionCart;
|
||||
|
||||
vec3 ray_end = ray_origin + ray_dir * depth;
|
||||
float t_max = depth;
|
||||
|
||||
if (length(ray_end) <= (get_earth_radius() + RADIUS_OFFSET)) {
|
||||
ray_end = normalize(ray_end) * (get_earth_radius() + RADIUS_OFFSET + 1.0);
|
||||
|
||||
ray_dir = ray_end - ray_origin;
|
||||
t_max = length(ray_dir);
|
||||
ray_dir /= max(t_max, 1e-5);
|
||||
}
|
||||
|
||||
vec4 transmittance;
|
||||
vec4 L = compute_inscattering(ray_origin,
|
||||
ray_dir,
|
||||
t_max,
|
||||
depth,
|
||||
fg_SunDirectionWorld,
|
||||
AERIAL_PERSPECTIVE_STEPS,
|
||||
transmittance_lut,
|
||||
|
|
|
@ -46,16 +46,10 @@ 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,
|
||||
t_max,
|
||||
1e7,
|
||||
sun_dir,
|
||||
SKY_STEPS,
|
||||
transmittance_lut,
|
||||
|
|
|
@ -40,7 +40,7 @@ void main()
|
|||
vec3 sun_radiance = get_sun_radiance_sea_level();
|
||||
|
||||
vec3 N = normalize(fs_in.vertex_normal);
|
||||
float NdotL = max(dot(N, fg_SunDirectionWorld), 1e-4);
|
||||
float NdotL = max(0.0, dot(N, fg_SunDirectionWorld));
|
||||
|
||||
// Assume a perfectly diffuse Lambertian surface
|
||||
color = M_1_PI() * color * sun_radiance * NdotL;
|
||||
|
|
Loading…
Add table
Reference in a new issue