From 9bc91682303d4370de025bcd7299e99d6971250f Mon Sep 17 00:00:00 2001 From: Hirek193 Date: Thu, 29 Oct 2026 19:04:57 +0100 Subject: [PATCH] Keep the contact shadow march and the traced reflections off NaN normals --- shaders/ogl46/light_common.glsl | 5 +++-- shaders/vk14/light_common.glsl | 5 +++-- shaders/vk14/rt_reflections.glsl | 3 +++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/shaders/ogl46/light_common.glsl b/shaders/ogl46/light_common.glsl index 67c3320c..c87658b4 100644 --- a/shaders/ogl46/light_common.glsl +++ b/shaders/ogl46/light_common.glsl @@ -82,7 +82,8 @@ float contact_shadow(vec3 light_dir, float raylength, float steps) vec3 normal = normalize(f_normal); if (dot(normal, position) > 0.0) normal = -normal; - if (dot(normal, light_dir) <= 0.0) + // (not "<= 0.0": a model with a normal of zero length gives NaN here, and the march with it would fetch far out of the depth) + if (!(dot(normal, light_dir) > 0.0)) return 0.0; vec2 size = vec2(textureSize(scene_depth, 0)); // the projection is perspective with the depth n / w (reverse z, infinite far plane): w is the distance along the axis @@ -105,7 +106,7 @@ float contact_shadow(vec3 light_dir, float raylength, float steps) vec2 coords = (clip.xy / clip.w) * 0.5 + 0.5; if (any(lessThan(coords, vec2(0.0))) || any(greaterThan(coords, vec2(1.0)))) break; - float depth = texelFetch(scene_depth, min(ivec2(coords * size), ivec2(size) - 1), 0).r; + float depth = texelFetch(scene_depth, clamp(ivec2(coords * size), ivec2(0), ivec2(size) - 1), 0).r; // nothing drawn there (the sky) if (depth <= 0.0) continue; diff --git a/shaders/vk14/light_common.glsl b/shaders/vk14/light_common.glsl index e2bd2f84..a83b1bab 100644 --- a/shaders/vk14/light_common.glsl +++ b/shaders/vk14/light_common.glsl @@ -86,7 +86,8 @@ float contact_shadow(vec3 light_dir, float raylength, float steps) vec3 normal = normalize(f_normal); if (dot(normal, position) > 0.0) normal = -normal; - if (dot(normal, light_dir) <= 0.0) + // (not "<= 0.0": a model with a normal of zero length gives NaN here, and the march with it would fetch far out of the depth) + if (!(dot(normal, light_dir) > 0.0)) return 0.0; vec2 size = vec2(textureSize(scene_depth, 0)); // the projection is perspective with the depth n / w (reverse z, infinite far plane): w is the distance along the axis @@ -109,7 +110,7 @@ float contact_shadow(vec3 light_dir, float raylength, float steps) vec2 coords = (clip.xy / clip.w) * 0.5 + 0.5; if (any(lessThan(coords, vec2(0.0))) || any(greaterThan(coords, vec2(1.0)))) break; - float depth = texelFetch(scene_depth, min(ivec2(coords * size), ivec2(size) - 1), 0).r; + float depth = texelFetch(scene_depth, clamp(ivec2(coords * size), ivec2(0), ivec2(size) - 1), 0).r; // nothing drawn there (the sky) if (depth <= 0.0) continue; diff --git a/shaders/vk14/rt_reflections.glsl b/shaders/vk14/rt_reflections.glsl index 65c7ec04..414e92e5 100644 --- a/shaders/vk14/rt_reflections.glsl +++ b/shaders/vk14/rt_reflections.glsl @@ -165,6 +165,9 @@ vec4 rt_trace(vec3 position, vec3 normal, vec3 direction, float roughness) if (dot(face, point) > 0.0) face = -face; vec3 ray = normalize(toworld * direction); + // a normal of zero length (a model without proper normals) gives NaN: a ray from such an origin is undefined + if (any(isnan(face)) || any(isnan(ray))) + return vec4(0.0); vec3 origin = point + face * (0.02 + length(point) * 0.0005); rayQueryEXT query;