diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index db6e1d38d1..e1db10af22 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -676,6 +676,21 @@ void RasterizerSceneGLES3::_setup_sky(const RenderDataGLES3 *p_render_data, cons ERR_FAIL_NULL(shader_data); if (sky) { + RSE::SkyMode sky_mode = sky->mode; + + if (sky_mode == RSE::SKY_MODE_AUTOMATIC) { + bool sun_scatter_enabled = environment_get_fog_enabled(p_render_data->environment) && environment_get_fog_sun_scatter(p_render_data->environment) > 0.001; + + if (shader_data->uses_time || shader_data->uses_position) { + sky_mode = RSE::SKY_MODE_REALTIME; + } else if (shader_data->uses_light || sun_scatter_enabled || shader_data->ubo_size > 0) { + sky_mode = RSE::SKY_MODE_INCREMENTAL; + } else { + sky_mode = RSE::SKY_MODE_QUALITY; + } + } + sky->internal_mode = sky_mode; + if (shader_data->uses_time && time - sky->prev_time > 0.00001) { sky->prev_time = time; sky->reflection_dirty = true; @@ -938,23 +953,8 @@ void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_p ERR_FAIL_NULL(shader_data); - bool update_single_frame = sky->mode == RSE::SKY_MODE_REALTIME || sky->mode == RSE::SKY_MODE_QUALITY; - RSE::SkyMode sky_mode = sky->mode; - - if (sky_mode == RSE::SKY_MODE_AUTOMATIC) { - bool sun_scatter_enabled = environment_get_fog_enabled(p_env) && environment_get_fog_sun_scatter(p_env) > 0.001; - - if ((shader_data->uses_time || shader_data->uses_position) && sky->radiance_size == 256) { - update_single_frame = true; - sky_mode = RSE::SKY_MODE_REALTIME; - } else if (shader_data->uses_light || sun_scatter_enabled || shader_data->ubo_size > 0) { - update_single_frame = false; - sky_mode = RSE::SKY_MODE_INCREMENTAL; - } else { - update_single_frame = true; - sky_mode = RSE::SKY_MODE_QUALITY; - } - } + RSE::SkyMode sky_mode = sky->internal_mode; + bool update_single_frame = sky_mode == RSE::SKY_MODE_REALTIME || sky_mode == RSE::SKY_MODE_QUALITY; if (sky->processing_layer == 0 && sky_mode == RSE::SKY_MODE_INCREMENTAL) { // On the first frame after creating sky, rebuild in single frame diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 948f216a71..cc3bbdd90e 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -815,6 +815,7 @@ protected: int mipmap_count = 1; RSE::SkyMode mode = RSE::SKY_MODE_AUTOMATIC; + RSE::SkyMode internal_mode = RSE::SKY_MODE_INCREMENTAL; // When using SKY_MODE_AUTOMATIC, this is the mode used internally. //ReflectionData reflection; bool reflection_dirty = false; diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index 91fca3b267..ff61196112 100644 --- a/servers/rendering/renderer_rd/environment/sky.cpp +++ b/servers/rendering/renderer_rd/environment/sky.cpp @@ -998,6 +998,32 @@ void SkyRD::setup_sky(const RenderDataRD *p_render_data, const Size2i p_screen_s sky->screen_size.x = p_screen_size.x < 4 ? 4 : p_screen_size.x; sky->screen_size.y = p_screen_size.y < 4 ? 4 : p_screen_size.y; + RSE::SkyMode sky_mode = sky->mode; + + if (sky_mode == RSE::SKY_MODE_AUTOMATIC) { + bool sun_scatter_enabled = RendererSceneRenderRD::get_singleton()->environment_get_fog_enabled(p_render_data->environment) && RendererSceneRenderRD::get_singleton()->environment_get_fog_sun_scatter(p_render_data->environment) > 0.001; + + if ((shader_data->uses_time || shader_data->uses_position) && sky->radiance_size == Sky::REAL_TIME_SIZE) { + sky_mode = RSE::SKY_MODE_REALTIME; + } else if (shader_data->uses_light || sun_scatter_enabled || shader_data->ubo_size > 0) { + sky_mode = RSE::SKY_MODE_INCREMENTAL; + } else { + sky_mode = RSE::SKY_MODE_QUALITY; + } + + if (sky_mode != sky->internal_mode) { + sky->internal_mode = sky_mode; + + if (sky->radiance.is_valid()) { + RD::get_singleton()->free_rid(sky->radiance); + sky->radiance = RID(); + } + sky->reflection.clear_reflection_data(); + } + } else { + sky->internal_mode = sky_mode; + } + // Trigger updating radiance buffers. if (sky->radiance.is_null()) { invalidate_sky(sky); @@ -1231,23 +1257,8 @@ void SkyRD::update_radiance_buffers(Ref p_render_buffers, ERR_FAIL_NULL(shader_data); - bool update_single_frame = sky->mode == RSE::SKY_MODE_REALTIME || sky->mode == RSE::SKY_MODE_QUALITY; - RSE::SkyMode sky_mode = sky->mode; - - if (sky_mode == RSE::SKY_MODE_AUTOMATIC) { - bool sun_scatter_enabled = RendererSceneRenderRD::get_singleton()->environment_get_fog_enabled(p_env) && RendererSceneRenderRD::get_singleton()->environment_get_fog_sun_scatter(p_env) > 0.001; - - if ((shader_data->uses_time || shader_data->uses_position) && sky->radiance_size == Sky::REAL_TIME_SIZE) { - update_single_frame = true; - sky_mode = RSE::SKY_MODE_REALTIME; - } else if (shader_data->uses_light || sun_scatter_enabled || shader_data->ubo_size > 0) { - update_single_frame = false; - sky_mode = RSE::SKY_MODE_INCREMENTAL; - } else { - update_single_frame = true; - sky_mode = RSE::SKY_MODE_QUALITY; - } - } + RSE::SkyMode sky_mode = sky->internal_mode; + bool update_single_frame = sky_mode == RSE::SKY_MODE_REALTIME || sky_mode == RSE::SKY_MODE_QUALITY; if (sky->processing_layer == 0 && sky_mode == RSE::SKY_MODE_INCREMENTAL) { // On the first frame after creating sky, rebuild in single frame @@ -1531,11 +1542,9 @@ void SkyRD::update_dirty_skys() { int mipmaps = Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBAH) + 1; int layers = roughness_layers; - if (sky->mode == RSE::SKY_MODE_REALTIME) { + bool use_realtime = sky->mode == RSE::SKY_MODE_REALTIME || sky->internal_mode == RSE::SKY_MODE_REALTIME; + if (use_realtime) { layers = Sky::REAL_TIME_ROUGHNESS_LAYERS; - if (roughness_layers != layers) { - WARN_PRINT(vformat("When using the Real-Time sky update mode (or Automatic with a sky shader using \"TIME\"), \"rendering/reflections/sky_reflections/roughness_layers\" should be set to %d in the project settings for best quality reflections.", Sky::REAL_TIME_ROUGHNESS_LAYERS)); - } } if (sky_use_octmap_array) { @@ -1561,7 +1570,7 @@ void SkyRD::update_dirty_skys() { sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView()); - sky->reflection.update_reflection_data(w, mipmaps, true, sky->radiance, 0, sky->mode == RSE::SKY_MODE_REALTIME, roughness_layers, texture_format, sky->uv_border_size); + sky->reflection.update_reflection_data(w, mipmaps, true, sky->radiance, 0, use_realtime, roughness_layers, texture_format, sky->uv_border_size); } else { // Double size to approximate texel density of cubemaps + add border for proper filtering/mipmapping. uint32_t padding_pixels = (1 << (MIN(mipmaps, layers) - 1)); @@ -1582,7 +1591,7 @@ void SkyRD::update_dirty_skys() { sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView()); - sky->reflection.update_reflection_data(w, MIN(mipmaps, layers), false, sky->radiance, 0, sky->mode == RSE::SKY_MODE_REALTIME, roughness_layers, texture_format, sky->uv_border_size); + sky->reflection.update_reflection_data(w, MIN(mipmaps, layers), false, sky->radiance, 0, use_realtime, roughness_layers, texture_format, sky->uv_border_size); } } diff --git a/servers/rendering/renderer_rd/environment/sky.h b/servers/rendering/renderer_rd/environment/sky.h index 07801dd750..44d89807db 100644 --- a/servers/rendering/renderer_rd/environment/sky.h +++ b/servers/rendering/renderer_rd/environment/sky.h @@ -262,6 +262,7 @@ public: float uv_border_size = 0.0; // Border size in UV space. RSE::SkyMode mode = RSE::SKY_MODE_AUTOMATIC; + RSE::SkyMode internal_mode = RSE::SKY_MODE_INCREMENTAL; // When using SKY_MODE_AUTOMATIC, this is the mode used internally. ReflectionData reflection; bool dirty = false;