From 9ba193252700da1a26d41d8c5b57d3d2cf950d75 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Tue, 14 Dec 2021 16:30:51 +0100 Subject: [PATCH] Add High Quality Once update mode to Sky This allows for generating high-quality reflections once when the sky resource is first assigned (or when the project starts). The use case is to use sky shaders that feature real-time clouds and the like without impacting performance nearly as much, since the radiance map is no longer constantly regenereated during gameplay. --- doc/classes/RenderingServer.xml | 9 ++++++--- scene/resources/sky.cpp | 2 +- .../renderer_rd/renderer_scene_sky_rd.cpp | 20 +++++++++++++------ servers/rendering_server.cpp | 1 + servers/rendering_server.h | 1 + 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 0700650a915d..6853e4ae82b5 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -4026,12 +4026,15 @@ - + + Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant Sky.PROCESS_MODE_REALTIME] but takes much longer to generate. Run-time updates are disabled to improve performance (at the cost of the radiance map being incorrect if the sky changes too much). Swapping the sky resource for another one will force the radiance map to update (but changing its properties won't). If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/reflections/sky_reflections/ggx_samples]. + + Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant Sky.PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/reflections/sky_reflections/ggx_samples]. - + - + Uses the fast filtering algorithm to process the radiance map. In general this results in lower quality, but substantially faster run times. [b]Note:[/b] The fast filtering algorithm is limited to 256x256 cubemaps, so [member Sky.radiance_size] must be set to [constant Sky.RADIANCE_SIZE_256]. diff --git a/scene/resources/sky.cpp b/scene/resources/sky.cpp index 71424ba8acff..ffef219fb01a 100644 --- a/scene/resources/sky.cpp +++ b/scene/resources/sky.cpp @@ -83,7 +83,7 @@ void Sky::_bind_methods() { ClassDB::bind_method(D_METHOD("get_material"), &Sky::get_material); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "sky_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,PanoramaSkyMaterial,ProceduralSkyMaterial,PhysicalSkyMaterial"), "set_material", "get_material"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Automatic,HighQuality,HighQualityIncremental,RealTime"), "set_process_mode", "get_process_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Automatic,High Quality Once (Fastest),High Quality (Slow),High Quality Incremental (Average),Real-Time (Fast)"), "set_process_mode", "get_process_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "radiance_size", PROPERTY_HINT_ENUM, "32,64,128,256,512,1024,2048"), "set_radiance_size", "get_radiance_size"); BIND_ENUM_CONSTANT(RADIANCE_SIZE_32); diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp index f595edb225f0..cd342fdbcaf8 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp @@ -1228,7 +1228,8 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM float multiplier = p_env->bg_energy; - bool update_single_frame = sky->mode == RS::SKY_MODE_REALTIME || sky->mode == RS::SKY_MODE_QUALITY; + bool should_update_sky = sky->reflection.dirty && sky->mode != RS::SKY_MODE_QUALITY_ONCE; + bool update_single_frame = sky->mode == RS::SKY_MODE_REALTIME || sky->mode == RS::SKY_MODE_QUALITY || sky->mode == RS::SKY_MODE_QUALITY_ONCE; RS::SkyMode sky_mode = sky->mode; if (sky_mode == RS::SKY_MODE_AUTOMATIC) { @@ -1244,16 +1245,23 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM } } - if (sky->processing_layer == 0 && sky_mode == RS::SKY_MODE_INCREMENTAL) { - // On the first frame after creating sky, rebuild in single frame - update_single_frame = true; - sky_mode = RS::SKY_MODE_QUALITY; + if (sky->processing_layer == 0) { + if (sky_mode == RS::SKY_MODE_QUALITY_ONCE) { + // Only update the sky once after it was created. + should_update_sky = true; + } + + if (sky_mode == RS::SKY_MODE_INCREMENTAL) { + // On the first frame after creating sky, rebuild in single frame + update_single_frame = true; + sky_mode = RS::SKY_MODE_QUALITY; + } } int max_processing_layer = sky_use_cubemap_array ? sky->reflection.layers.size() : sky->reflection.layers[0].mipmaps.size(); // Update radiance cubemap - if (sky->reflection.dirty && (sky->processing_layer >= max_processing_layer || update_single_frame)) { + if (should_update_sky && (sky->processing_layer >= max_processing_layer || update_single_frame)) { static const Vector3 view_normals[6] = { Vector3(+1, 0, 0), Vector3(-1, 0, 0), diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 23d3bf030f7d..efc2dd021a26 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2295,6 +2295,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("sky_bake_panorama", "sky", "energy", "bake_irradiance", "size"), &RenderingServer::sky_bake_panorama); BIND_ENUM_CONSTANT(SKY_MODE_AUTOMATIC); + BIND_ENUM_CONSTANT(SKY_MODE_QUALITY_ONCE); BIND_ENUM_CONSTANT(SKY_MODE_QUALITY); BIND_ENUM_CONSTANT(SKY_MODE_INCREMENTAL); BIND_ENUM_CONSTANT(SKY_MODE_REALTIME); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 230132651fba..d984b47dd6f4 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -936,6 +936,7 @@ class RenderingServer : public Object { enum SkyMode { SKY_MODE_AUTOMATIC, + SKY_MODE_QUALITY_ONCE, SKY_MODE_QUALITY, SKY_MODE_INCREMENTAL, SKY_MODE_REALTIME