From d27e4dab1674caa822dfbb1e0ae92a08e4580c75 Mon Sep 17 00:00:00 2001 From: Skyth <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Thu, 13 Nov 2025 16:38:54 +0300 Subject: [PATCH] Sanitize INF/NaN when copying last frame texture for SSIL/SSR. --- servers/rendering/renderer_rd/effects/copy_effects.cpp | 6 +++++- servers/rendering/renderer_rd/effects/copy_effects.h | 3 ++- servers/rendering/renderer_rd/effects/ss_effects.cpp | 2 +- servers/rendering/renderer_rd/shaders/effects/copy.glsl | 6 ++++++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp index 8fdb9d2ffa8..41b2104135e 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.cpp +++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp @@ -358,7 +358,7 @@ CopyEffects::~CopyEffects() { singleton = nullptr; } -void CopyEffects::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_all_source, bool p_8_bit_dst, bool p_alpha_to_one) { +void CopyEffects::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_all_source, bool p_8_bit_dst, bool p_alpha_to_one, bool p_sanitize_inf_nan) { UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); ERR_FAIL_NULL(uniform_set_cache); MaterialStorage *material_storage = MaterialStorage::get_singleton(); @@ -381,6 +381,10 @@ void CopyEffects::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, cons copy.push_constant.flags |= COPY_FLAG_ALPHA_TO_ONE; } + if (p_sanitize_inf_nan) { + copy.push_constant.flags |= COPY_FLAG_SANITIZE_INF_NAN; + } + copy.push_constant.section[0] = p_rect.position.x; copy.push_constant.section[1] = p_rect.position.y; copy.push_constant.section[2] = p_rect.size.width; diff --git a/servers/rendering/renderer_rd/effects/copy_effects.h b/servers/rendering/renderer_rd/effects/copy_effects.h index f40467670b0..a9842fd261b 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.h +++ b/servers/rendering/renderer_rd/effects/copy_effects.h @@ -131,6 +131,7 @@ private: COPY_FLAG_FORCE_LUMINANCE = (1 << 6), COPY_FLAG_ALL_SOURCE = (1 << 7), COPY_FLAG_ALPHA_TO_ONE = (1 << 8), + COPY_FLAG_SANITIZE_INF_NAN = (1 << 9), }; struct CopyPushConstant { @@ -323,7 +324,7 @@ public: bool get_prefer_raster_effects() { return prefer_raster_effects; } - void copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_all_source = false, bool p_8_bit_dst = false, bool p_alpha_to_one = false); + void copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_all_source = false, bool p_8_bit_dst = false, bool p_alpha_to_one = false, bool p_sanitize_inf_nan = false); void copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array); void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false); void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far); diff --git a/servers/rendering/renderer_rd/effects/ss_effects.cpp b/servers/rendering/renderer_rd/effects/ss_effects.cpp index 971bd61abcd..7e10a40e7dd 100644 --- a/servers/rendering/renderer_rd/effects/ss_effects.cpp +++ b/servers/rendering/renderer_rd/effects/ss_effects.cpp @@ -412,7 +412,7 @@ void SSEffects::copy_internal_texture_to_last_frame(Ref p_ Size2i dest_size = RD::get_singleton()->texture_size(dest); if (m == 0 && source_size == dest_size) { - p_copy_effects.copy_to_rect(source, dest, Rect2i(Vector2i(), source_size)); + p_copy_effects.copy_to_rect(source, dest, Rect2i(Vector2i(), source_size), false, false, false, false, false, true); } else { p_copy_effects.make_mipmap(source, dest, dest_size); } diff --git a/servers/rendering/renderer_rd/shaders/effects/copy.glsl b/servers/rendering/renderer_rd/shaders/effects/copy.glsl index fa8e0590fc9..f01c7ec7301 100644 --- a/servers/rendering/renderer_rd/shaders/effects/copy.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/copy.glsl @@ -15,6 +15,7 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; #define FLAG_FORCE_LUMINANCE (1 << 6) #define FLAG_COPY_ALL_SOURCE (1 << 7) #define FLAG_ALPHA_TO_ONE (1 << 8) +#define FLAG_SANITIZE_INF_NAN (1 << 9) layout(push_constant, std430) uniform Params { ivec4 section; @@ -226,6 +227,11 @@ void main() { color.a = 1.0; } + if (bool(params.flags & FLAG_SANITIZE_INF_NAN)) { + color = mix(color, vec4(100.0, 100.0, 100.0, 1.0), isinf(color)); + color = mix(color, vec4(100.0, 100.0, 100.0, 1.0), isnan(color)); + } + imageStore(dest_buffer, pos + params.target, color); #endif // MODE_SIMPLE_COPY