diff --git a/Shaders/HDR/atmos.glsl b/Shaders/HDR/atmos.glsl index cb6d91b81..1101eca1c 100644 --- a/Shaders/HDR/atmos.glsl +++ b/Shaders/HDR/atmos.glsl @@ -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 diff --git a/Shaders/HDR/atmos_aerial_perspective.frag b/Shaders/HDR/atmos_aerial_perspective.frag index 053a928a4..69b644353 100644 --- a/Shaders/HDR/atmos_aerial_perspective.frag +++ b/Shaders/HDR/atmos_aerial_perspective.frag @@ -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; diff --git a/Shaders/HDR/clustered.glsl b/Shaders/HDR/clustered.glsl index 9dc9738b5..d52ec6a8b 100644 --- a/Shaders/HDR/clustered.glsl +++ b/Shaders/HDR/clustered.glsl @@ -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) diff --git a/Shaders/HDR/math.glsl b/Shaders/HDR/math.glsl index 748e6d030..bfcc19fd5 100644 --- a/Shaders/HDR/math.glsl +++ b/Shaders/HDR/math.glsl @@ -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)); } diff --git a/Shaders/HDR/skydome.frag b/Shaders/HDR/skydome.frag index 75890da9f..fd5d3fcd8 100644 --- a/Shaders/HDR/skydome.frag +++ b/Shaders/HDR/skydome.frag @@ -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)); diff --git a/Shaders/HDR/surface.glsl b/Shaders/HDR/surface.glsl index f4a8629f6..9e40f1bb5 100644 --- a/Shaders/HDR/surface.glsl +++ b/Shaders/HDR/surface.glsl @@ -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;