From 7b923609c2995101130d74577a406da068c1ea11 Mon Sep 17 00:00:00 2001 From: Dario Date: Mon, 8 Sep 2025 15:54:37 -0300 Subject: [PATCH] Fix reflection probes not recreating downsampled textures when mode changes. --- .../renderer_rd/storage_rd/light_storage.cpp | 12 ++++++++---- .../rendering/renderer_rd/storage_rd/light_storage.h | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp index 8f319d430aa..bfbf85aa350 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp @@ -1495,12 +1495,15 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_ RD::get_singleton()->draw_command_begin_label("Reflection probe render"); - if (LightStorage::get_singleton()->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS && atlas->reflection.is_valid() && atlas->size != 256) { + const bool update_always = LightStorage::get_singleton()->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS; + if (update_always && atlas->reflection.is_valid() && atlas->size != 256) { WARN_PRINT("ReflectionProbes set to UPDATE_ALWAYS must have an atlas size of 256. Please update the atlas size in the ProjectSettings."); reflection_atlas_set_size(p_reflection_atlas, 256, atlas->count); } - if (LightStorage::get_singleton()->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS && atlas->reflection.is_valid() && atlas->reflections[0].data.layers[0].mipmaps.size() != 8) { + const bool update_mode_changed = atlas->update_always != update_always && atlas->reflection.is_valid(); + const bool real_time_mipmaps_different = update_always && atlas->reflection.is_valid() && atlas->reflections[0].data.layers[0].mipmaps.size() != 8; + if (update_mode_changed || real_time_mipmaps_different) { // Invalidate reflection atlas, need to regenerate RD::get_singleton()->free(atlas->reflection); atlas->reflection = RID(); @@ -1517,7 +1520,7 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_ if (atlas->reflection.is_null()) { int mipmaps = MIN(RendererSceneRenderRD::get_singleton()->get_sky()->roughness_layers, Image::get_image_required_mipmaps(atlas->size, atlas->size, Image::FORMAT_RGBAH) + 1); - mipmaps = LightStorage::get_singleton()->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS ? 8 : mipmaps; // always use 8 mipmaps with real time filtering + mipmaps = update_always ? 8 : mipmaps; // always use 8 mipmaps with real time filtering { //reflection atlas was unused, create: RD::TextureFormat tf; @@ -1540,7 +1543,7 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_ } atlas->reflections.resize(atlas->count); for (int i = 0; i < atlas->count; i++) { - atlas->reflections.write[i].data.update_reflection_data(atlas->size, mipmaps, false, atlas->reflection, i * 6, LightStorage::get_singleton()->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS, RendererSceneRenderRD::get_singleton()->get_sky()->roughness_layers, RendererSceneRenderRD::get_singleton()->_render_buffers_get_color_format()); + atlas->reflections.write[i].data.update_reflection_data(atlas->size, mipmaps, false, atlas->reflection, i * 6, update_always, RendererSceneRenderRD::get_singleton()->get_sky()->roughness_layers, RendererSceneRenderRD::get_singleton()->_render_buffers_get_color_format()); for (int j = 0; j < 6; j++) { atlas->reflections.write[i].fbs[j] = RendererSceneRenderRD::get_singleton()->reflection_probe_create_framebuffer(atlas->reflections.write[i].data.layers[0].mipmaps[0].views[j], atlas->depth_buffer); } @@ -1551,6 +1554,7 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_ atlas->depth_fb = RD::get_singleton()->framebuffer_create(fb); atlas->render_buffers->configure_for_reflections(Size2i(atlas->size, atlas->size)); + atlas->update_always = update_always; } if (rpi->atlas_index == -1) { diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.h b/servers/rendering/renderer_rd/storage_rd/light_storage.h index 75a9a566a58..0d60da5811e 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.h @@ -246,6 +246,7 @@ private: struct ReflectionAtlas { int count = 0; int size = 0; + bool update_always = false; RID reflection; RID depth_buffer;