1
0
Fork 0

HDR: Safer divisions

This commit is contained in:
Fernando García Liñán 2024-02-08 22:37:07 +01:00
parent dd97ee58db
commit 7b5255eac4
6 changed files with 14 additions and 8 deletions

View file

@ -240,7 +240,7 @@ float get_ray_end(vec3 ray_origin, vec3 ray_dir, float t_max)
// 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);
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

View file

@ -68,7 +68,7 @@ void main()
ray_dir = ray_end - ray_origin;
t_max = length(ray_dir);
ray_dir /= t_max;
ray_dir /= max(t_max, 1e-5);
}
vec4 transmittance;

View file

@ -80,12 +80,13 @@ int getIndex(int counter)
return int(texture(fg_ClusteredIndices, coords).r);
}
float get_square_falloff_attenuation(vec3 to_light, float inv_range)
float get_square_falloff_attenuation(vec3 to_light, float range)
{
float inv_range = 1.0 / max(range, 1e-5);
float dd = dot(to_light, to_light);
float factor = dd * inv_range * inv_range;
float smooth_factor = max(1.0 - factor * factor, 0.0);
return (smooth_factor * smooth_factor) / max(dd, 0.0001);
return (smooth_factor * smooth_factor) / max(dd, 1e-5);
}
float get_spot_angle_attenuation(vec3 l, vec3 light_dir,
@ -124,7 +125,7 @@ vec3 eval_scene_lights(vec3 base_color, float metallic, float roughness, vec3 f0
vec3 L = normalize(to_light);
float attenuation = get_square_falloff_attenuation(
to_light, 1.0 / light.range);
to_light, light.range);
if (attenuation <= 0.0)
continue;
@ -144,7 +145,7 @@ vec3 eval_scene_lights(vec3 base_color, float metallic, float roughness, vec3 f0
vec3 L = normalize(to_light);
float attenuation = get_square_falloff_attenuation(
to_light, 1.0 / light.range);
to_light, light.range);
attenuation *= get_spot_angle_attenuation(
L, light.direction, light.cos_cutoff, light.exponent);
if (attenuation <= 0.0)

View file

@ -26,6 +26,10 @@ float safe_sqrt(float x) {
return sqrt(max(x, 0.0));
}
float safe_asin(float x) {
return asin(clamp(x, -1.0, 1.0));
}
float safe_acos(float x) {
return acos(clamp(x, -1.0, 1.0));
}

View file

@ -24,6 +24,7 @@ const float SUN_SIN_HALF_ANGULAR_DIAMETER = 0.0047560042817014138; // sin(radian
float M_PI();
float sqr(float x);
float saturate(float x);
float safe_asin(float x);
// atmos_spectral.glsl
vec4 get_sun_spectral_irradiance();
vec3 linear_srgb_from_spectral_samples(vec4 L);
@ -51,7 +52,7 @@ void main()
vec3 frag_ray_dir = normalize(ray_dir);
float azimuth = atan(frag_ray_dir.y, frag_ray_dir.x) / M_PI() * 0.5 + 0.5;
// Undo the non-linear transformation from the sky-view LUT
float l = asin(frag_ray_dir.z);
float l = safe_asin(frag_ray_dir.z);
float elev = sqrt(abs(l) / (M_PI() * 0.5)) * sign(l) * 0.5 + 0.5;
vec4 sky_radiance = texture(sky_view_tex, vec2(azimuth, elev));

View file

@ -87,7 +87,7 @@ vec3 surface_eval_analytical(
float G = G1_Smith_GGX(NdotV, a2) * G1_Smith_GGX(NdotL, a2);
float D = D_GGX(NdotH, a2);
vec3 f_specular = (F * a2) / (D * G);
vec3 f_specular = (F * a2) / max(D * G, 1e-5);
vec3 f_diffuse = (vec3(1.0) - F) * c_diff * M_1_PI();
vec3 bsdf = f_diffuse + f_specular;