diff options
-rw-r--r-- | doc/classes/Light3D.xml | 44 | ||||
-rw-r--r-- | doc/classes/RenderingServer.xml | 39 | ||||
-rw-r--r-- | drivers/gles3/storage/light_storage.cpp | 2 | ||||
-rw-r--r-- | drivers/gles3/storage/light_storage.h | 7 | ||||
-rw-r--r-- | scene/3d/light_3d.cpp | 8 | ||||
-rw-r--r-- | scene/3d/light_3d.h | 2 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/renderer_scene_render_rd.cpp | 4 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/renderer_scene_render_rd.h | 4 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl | 89 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/shaders/light_data_inc.glsl | 4 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/storage_rd/light_storage.cpp | 2 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/storage_rd/light_storage.h | 7 | ||||
-rw-r--r-- | servers/rendering_server.cpp | 2 | ||||
-rw-r--r-- | servers/rendering_server.h | 2 |
14 files changed, 105 insertions, 111 deletions
diff --git a/doc/classes/Light3D.xml b/doc/classes/Light3D.xml index 80ff83ec46..cc8484d9fa 100644 --- a/doc/classes/Light3D.xml +++ b/doc/classes/Light3D.xml @@ -80,6 +80,10 @@ <member name="light_specular" type="float" setter="set_param" getter="get_param" default="0.5"> The intensity of the specular blob in objects affected by the light. At [code]0[/code], the light becomes a pure diffuse light. When not baking emission, this can be used to avoid unrealistic reflections when placing lights above an emissive surface. </member> + <member name="light_volumetric_fog_energy" type="float" setter="set_param" getter="get_param" default="1.0"> + Secondary multiplier multiplied with [member light_energy] then used with the [Environment]'s volumetric fog (if enabled). If set to [code]0.0[/code], computing volumetric fog will be skipped for this light, which can improve performance for large amounts of lights when volumetric fog is enabled. + [b]Note:[/b] To prevent short-lived dynamic light effects from poorly interacting with volumetric fog, lights used in those effects should have [member light_volumetric_fog_energy] set to [code]0.0[/code] unless [member Environment.volumetric_fog_temporal_reprojection_enabled] is disabled (or unless the reprojection amount is significantly lowered). + </member> <member name="shadow_bias" type="float" setter="set_param" getter="get_param" default="0.1"> Used to adjust shadow appearance. Too small a value results in self-shadowing ("shadow acne"), while too large a value causes shadows to separate from casters ("peter-panning"). Adjust as needed. </member> @@ -89,8 +93,6 @@ <member name="shadow_enabled" type="bool" setter="set_shadow" getter="has_shadow" default="false"> If [code]true[/code], the light will cast real-time shadows. This has a significant performance cost. Only enable shadow rendering when it makes a noticeable difference in the scene's appearance, and consider using [member distance_fade_enabled] to hide the light when far away from the [Camera3D]. </member> - <member name="shadow_fog_fade" type="float" setter="set_param" getter="get_param" default="0.1"> - </member> <member name="shadow_normal_bias" type="float" setter="set_param" getter="get_param" default="1.0"> Offsets the lookup into the shadow map by the object's normal. This can be used to reduce self-shadowing artifacts without using [member shadow_bias]. In practice, this value should be tweaked along with [member shadow_bias] to reduce artifacts as much as possible. </member> @@ -110,57 +112,57 @@ <constant name="PARAM_INDIRECT_ENERGY" value="1" enum="Param"> Constant for accessing [member light_indirect_energy]. </constant> - <constant name="PARAM_SPECULAR" value="2" enum="Param"> + <constant name="PARAM_VOLUMETRIC_FOG_ENERGY" value="2" enum="Param"> + Constant for accessing [member light_volumetric_fog_energy]. + </constant> + <constant name="PARAM_SPECULAR" value="3" enum="Param"> Constant for accessing [member light_specular]. </constant> - <constant name="PARAM_RANGE" value="3" enum="Param"> + <constant name="PARAM_RANGE" value="4" enum="Param"> Constant for accessing [member OmniLight3D.omni_range] or [member SpotLight3D.spot_range]. </constant> - <constant name="PARAM_SIZE" value="4" enum="Param"> + <constant name="PARAM_SIZE" value="5" enum="Param"> Constant for accessing [member light_size]. </constant> - <constant name="PARAM_ATTENUATION" value="5" enum="Param"> + <constant name="PARAM_ATTENUATION" value="6" enum="Param"> Constant for accessing [member OmniLight3D.omni_attenuation] or [member SpotLight3D.spot_attenuation]. </constant> - <constant name="PARAM_SPOT_ANGLE" value="6" enum="Param"> + <constant name="PARAM_SPOT_ANGLE" value="7" enum="Param"> Constant for accessing [member SpotLight3D.spot_angle]. </constant> - <constant name="PARAM_SPOT_ATTENUATION" value="7" enum="Param"> + <constant name="PARAM_SPOT_ATTENUATION" value="8" enum="Param"> Constant for accessing [member SpotLight3D.spot_angle_attenuation]. </constant> - <constant name="PARAM_SHADOW_MAX_DISTANCE" value="8" enum="Param"> + <constant name="PARAM_SHADOW_MAX_DISTANCE" value="9" enum="Param"> Constant for accessing [member DirectionalLight3D.directional_shadow_max_distance]. </constant> - <constant name="PARAM_SHADOW_SPLIT_1_OFFSET" value="9" enum="Param"> + <constant name="PARAM_SHADOW_SPLIT_1_OFFSET" value="10" enum="Param"> Constant for accessing [member DirectionalLight3D.directional_shadow_split_1]. </constant> - <constant name="PARAM_SHADOW_SPLIT_2_OFFSET" value="10" enum="Param"> + <constant name="PARAM_SHADOW_SPLIT_2_OFFSET" value="11" enum="Param"> Constant for accessing [member DirectionalLight3D.directional_shadow_split_2]. </constant> - <constant name="PARAM_SHADOW_SPLIT_3_OFFSET" value="11" enum="Param"> + <constant name="PARAM_SHADOW_SPLIT_3_OFFSET" value="12" enum="Param"> Constant for accessing [member DirectionalLight3D.directional_shadow_split_3]. </constant> - <constant name="PARAM_SHADOW_FADE_START" value="12" enum="Param"> + <constant name="PARAM_SHADOW_FADE_START" value="13" enum="Param"> Constant for accessing [member DirectionalLight3D.directional_shadow_fade_start]. </constant> - <constant name="PARAM_SHADOW_NORMAL_BIAS" value="13" enum="Param"> + <constant name="PARAM_SHADOW_NORMAL_BIAS" value="14" enum="Param"> Constant for accessing [member shadow_normal_bias]. </constant> - <constant name="PARAM_SHADOW_BIAS" value="14" enum="Param"> + <constant name="PARAM_SHADOW_BIAS" value="15" enum="Param"> Constant for accessing [member shadow_bias]. </constant> - <constant name="PARAM_SHADOW_PANCAKE_SIZE" value="15" enum="Param"> + <constant name="PARAM_SHADOW_PANCAKE_SIZE" value="16" enum="Param"> Constant for accessing [member DirectionalLight3D.directional_shadow_pancake_size]. </constant> - <constant name="PARAM_SHADOW_OPACITY" value="16" enum="Param"> + <constant name="PARAM_SHADOW_OPACITY" value="17" enum="Param"> Constant for accessing [member shadow_opacity]. </constant> - <constant name="PARAM_SHADOW_BLUR" value="17" enum="Param"> + <constant name="PARAM_SHADOW_BLUR" value="18" enum="Param"> Constant for accessing [member shadow_blur]. </constant> - <constant name="PARAM_SHADOW_VOLUMETRIC_FOG_FADE" value="18" enum="Param"> - Constant for accessing [member shadow_fog_fade]. - </constant> <constant name="PARAM_TRANSMITTANCE_BIAS" value="19" enum="Param"> Constant for accessing [member shadow_transmittance_bias]. </constant> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 755e8a5839..310e2334fb 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -3792,61 +3792,62 @@ Is a spot light. </constant> <constant name="LIGHT_PARAM_ENERGY" value="0" enum="LightParam"> - The light's energy. + The light's energy multiplier. </constant> <constant name="LIGHT_PARAM_INDIRECT_ENERGY" value="1" enum="LightParam"> The light's indirect energy multiplier (final indirect energy is [constant LIGHT_PARAM_ENERGY] * [constant LIGHT_PARAM_INDIRECT_ENERGY]). </constant> - <constant name="LIGHT_PARAM_SPECULAR" value="2" enum="LightParam"> + <constant name="LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY" value="2" enum="LightParam"> + The light's volumetric fog energy multiplier (final volumetric fog energy is [constant LIGHT_PARAM_ENERGY] * [constant LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY]). + </constant> + <constant name="LIGHT_PARAM_SPECULAR" value="3" enum="LightParam"> The light's influence on specularity. </constant> - <constant name="LIGHT_PARAM_RANGE" value="3" enum="LightParam"> + <constant name="LIGHT_PARAM_RANGE" value="4" enum="LightParam"> The light's range. </constant> - <constant name="LIGHT_PARAM_SIZE" value="4" enum="LightParam"> + <constant name="LIGHT_PARAM_SIZE" value="5" enum="LightParam"> The size of the light when using spot light or omni light. The angular size of the light when using directional light. </constant> - <constant name="LIGHT_PARAM_ATTENUATION" value="5" enum="LightParam"> + <constant name="LIGHT_PARAM_ATTENUATION" value="6" enum="LightParam"> The light's attenuation. </constant> - <constant name="LIGHT_PARAM_SPOT_ANGLE" value="6" enum="LightParam"> + <constant name="LIGHT_PARAM_SPOT_ANGLE" value="7" enum="LightParam"> The spotlight's angle. </constant> - <constant name="LIGHT_PARAM_SPOT_ATTENUATION" value="7" enum="LightParam"> + <constant name="LIGHT_PARAM_SPOT_ATTENUATION" value="8" enum="LightParam"> The spotlight's attenuation. </constant> - <constant name="LIGHT_PARAM_SHADOW_MAX_DISTANCE" value="8" enum="LightParam"> + <constant name="LIGHT_PARAM_SHADOW_MAX_DISTANCE" value="9" enum="LightParam"> Max distance that shadows will be rendered. </constant> - <constant name="LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET" value="9" enum="LightParam"> + <constant name="LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET" value="10" enum="LightParam"> Proportion of shadow atlas occupied by the first split. </constant> - <constant name="LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET" value="10" enum="LightParam"> + <constant name="LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET" value="11" enum="LightParam"> Proportion of shadow atlas occupied by the second split. </constant> - <constant name="LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET" value="11" enum="LightParam"> + <constant name="LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET" value="12" enum="LightParam"> Proportion of shadow atlas occupied by the third split. The fourth split occupies the rest. </constant> - <constant name="LIGHT_PARAM_SHADOW_FADE_START" value="12" enum="LightParam"> + <constant name="LIGHT_PARAM_SHADOW_FADE_START" value="13" enum="LightParam"> Proportion of shadow max distance where the shadow will start to fade out. </constant> - <constant name="LIGHT_PARAM_SHADOW_NORMAL_BIAS" value="13" enum="LightParam"> + <constant name="LIGHT_PARAM_SHADOW_NORMAL_BIAS" value="14" enum="LightParam"> Normal bias used to offset shadow lookup by object normal. Can be used to fix self-shadowing artifacts. </constant> - <constant name="LIGHT_PARAM_SHADOW_BIAS" value="14" enum="LightParam"> + <constant name="LIGHT_PARAM_SHADOW_BIAS" value="15" enum="LightParam"> Bias the shadow lookup to fix self-shadowing artifacts. </constant> - <constant name="LIGHT_PARAM_SHADOW_PANCAKE_SIZE" value="15" enum="LightParam"> + <constant name="LIGHT_PARAM_SHADOW_PANCAKE_SIZE" value="16" enum="LightParam"> Sets the size of the directional shadow pancake. The pancake offsets the start of the shadow's camera frustum to provide a higher effective depth resolution for the shadow. However, a high pancake size can cause artifacts in the shadows of large objects that are close to the edge of the frustum. Reducing the pancake size can help. Setting the size to [code]0[/code] turns off the pancaking effect. </constant> - <constant name="LIGHT_PARAM_SHADOW_OPACITY" value="16" enum="LightParam"> + <constant name="LIGHT_PARAM_SHADOW_OPACITY" value="17" enum="LightParam"> The light's shadow opacity. Values lower than [code]1.0[/code] make the light appear through shadows. This can be used to fake global illumination at a low performance cost. </constant> - <constant name="LIGHT_PARAM_SHADOW_BLUR" value="17" enum="LightParam"> + <constant name="LIGHT_PARAM_SHADOW_BLUR" value="18" enum="LightParam"> Blurs the edges of the shadow. Can be used to hide pixel artifacts in low resolution shadow maps. A high value can make shadows appear grainy and can cause other unwanted artifacts. Try to keep as near default as possible. </constant> - <constant name="LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE" value="18" enum="LightParam"> - </constant> <constant name="LIGHT_PARAM_TRANSMITTANCE_BIAS" value="19" enum="LightParam"> </constant> <constant name="LIGHT_PARAM_MAX" value="20" enum="LightParam"> diff --git a/drivers/gles3/storage/light_storage.cpp b/drivers/gles3/storage/light_storage.cpp index e2781bfbc0..683716ca99 100644 --- a/drivers/gles3/storage/light_storage.cpp +++ b/drivers/gles3/storage/light_storage.cpp @@ -58,6 +58,7 @@ void LightStorage::_light_initialize(RID p_light, RS::LightType p_type) { light.param[RS::LIGHT_PARAM_ENERGY] = 1.0; light.param[RS::LIGHT_PARAM_INDIRECT_ENERGY] = 1.0; + light.param[RS::LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY] = 1.0; light.param[RS::LIGHT_PARAM_SPECULAR] = 0.5; light.param[RS::LIGHT_PARAM_RANGE] = 1.0; light.param[RS::LIGHT_PARAM_SIZE] = 0.0; @@ -74,7 +75,6 @@ void LightStorage::_light_initialize(RID p_light, RS::LightType p_type) { light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02; light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0; light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0; - light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 0.1; light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05; light_owner.initialize_rid(p_light, light); diff --git a/drivers/gles3/storage/light_storage.h b/drivers/gles3/storage/light_storage.h index 857a0261fa..fa012a7b58 100644 --- a/drivers/gles3/storage/light_storage.h +++ b/drivers/gles3/storage/light_storage.h @@ -261,13 +261,6 @@ public: return light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS]; } - _FORCE_INLINE_ float light_get_shadow_volumetric_fog_fade(RID p_light) const { - const Light *light = light_owner.get_or_null(p_light); - ERR_FAIL_COND_V(!light, 0.0); - - return light->param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE]; - } - virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override; virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override { return 0; } virtual uint64_t light_get_version(RID p_light) const override; diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index 8d96d13f0c..66f4fa2bcc 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -224,7 +224,7 @@ bool Light3D::is_editor_only() const { } void Light3D::_validate_property(PropertyInfo &p_property) const { - if (!shadow && (p_property.name == "shadow_bias" || p_property.name == "shadow_normal_bias" || p_property.name == "shadow_reverse_cull_face" || p_property.name == "shadow_transmittance_bias" || p_property.name == "shadow_fog_fade" || p_property.name == "shadow_opacity" || p_property.name == "shadow_blur" || p_property.name == "distance_fade_shadow")) { + if (!shadow && (p_property.name == "shadow_bias" || p_property.name == "shadow_normal_bias" || p_property.name == "shadow_reverse_cull_face" || p_property.name == "shadow_transmittance_bias" || p_property.name == "shadow_opacity" || p_property.name == "shadow_blur" || p_property.name == "distance_fade_shadow")) { p_property.usage = PROPERTY_USAGE_NO_EDITOR; } @@ -282,6 +282,7 @@ void Light3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::COLOR, "light_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_color", "get_color"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_energy", PROPERTY_HINT_RANGE, "0,16,0.001,or_greater"), "set_param", "get_param", PARAM_ENERGY); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_indirect_energy", PROPERTY_HINT_RANGE, "0,16,0.001,or_greater"), "set_param", "get_param", PARAM_INDIRECT_ENERGY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_volumetric_fog_energy", PROPERTY_HINT_RANGE, "0,16,0.001,or_greater"), "set_param", "get_param", PARAM_VOLUMETRIC_FOG_ENERGY); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_projector", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_projector", "get_projector"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_size", PROPERTY_HINT_RANGE, "0,1,0.001,or_greater,suffix:m"), "set_param", "get_param", PARAM_SIZE); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_angular_distance", PROPERTY_HINT_RANGE, "0,90,0.01,degrees"), "set_param", "get_param", PARAM_SIZE); @@ -296,7 +297,6 @@ void Light3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_normal_bias", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_reverse_cull_face"), "set_shadow_reverse_cull_face", "get_shadow_reverse_cull_face"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_transmittance_bias", PROPERTY_HINT_RANGE, "-16,16,0.001"), "set_param", "get_param", PARAM_TRANSMITTANCE_BIAS); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_fog_fade", PROPERTY_HINT_RANGE, "0.001,10,0.001"), "set_param", "get_param", PARAM_SHADOW_VOLUMETRIC_FOG_FADE); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_opacity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_OPACITY); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_blur", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_BLUR); @@ -313,6 +313,7 @@ void Light3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_ENERGY); BIND_ENUM_CONSTANT(PARAM_INDIRECT_ENERGY); + BIND_ENUM_CONSTANT(PARAM_VOLUMETRIC_FOG_ENERGY); BIND_ENUM_CONSTANT(PARAM_SPECULAR); BIND_ENUM_CONSTANT(PARAM_RANGE); BIND_ENUM_CONSTANT(PARAM_SIZE); @@ -329,7 +330,6 @@ void Light3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_SHADOW_PANCAKE_SIZE); BIND_ENUM_CONSTANT(PARAM_SHADOW_OPACITY); BIND_ENUM_CONSTANT(PARAM_SHADOW_BLUR); - BIND_ENUM_CONSTANT(PARAM_SHADOW_VOLUMETRIC_FOG_FADE); BIND_ENUM_CONSTANT(PARAM_TRANSMITTANCE_BIAS); BIND_ENUM_CONSTANT(PARAM_MAX); @@ -363,6 +363,7 @@ Light3D::Light3D(RenderingServer::LightType p_type) { set_param(PARAM_ENERGY, 1); set_param(PARAM_INDIRECT_ENERGY, 1); + set_param(PARAM_VOLUMETRIC_FOG_ENERGY, 1); set_param(PARAM_SPECULAR, 0.5); set_param(PARAM_RANGE, 5); set_param(PARAM_SIZE, 0); @@ -380,7 +381,6 @@ Light3D::Light3D(RenderingServer::LightType p_type) { set_param(PARAM_SHADOW_BIAS, 0.03); set_param(PARAM_SHADOW_NORMAL_BIAS, 1.0); set_param(PARAM_TRANSMITTANCE_BIAS, 0.05); - set_param(PARAM_SHADOW_VOLUMETRIC_FOG_FADE, 0.1); set_param(PARAM_SHADOW_FADE_START, 1); set_disable_scale(true); } diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h index 035ba50e42..0792f21c6e 100644 --- a/scene/3d/light_3d.h +++ b/scene/3d/light_3d.h @@ -40,6 +40,7 @@ public: enum Param { PARAM_ENERGY = RS::LIGHT_PARAM_ENERGY, PARAM_INDIRECT_ENERGY = RS::LIGHT_PARAM_INDIRECT_ENERGY, + PARAM_VOLUMETRIC_FOG_ENERGY = RS::LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY, PARAM_SPECULAR = RS::LIGHT_PARAM_SPECULAR, PARAM_RANGE = RS::LIGHT_PARAM_RANGE, PARAM_SIZE = RS::LIGHT_PARAM_SIZE, @@ -56,7 +57,6 @@ public: PARAM_SHADOW_PANCAKE_SIZE = RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE, PARAM_SHADOW_OPACITY = RS::LIGHT_PARAM_SHADOW_OPACITY, PARAM_SHADOW_BLUR = RS::LIGHT_PARAM_SHADOW_BLUR, - PARAM_SHADOW_VOLUMETRIC_FOG_FADE = RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE, PARAM_TRANSMITTANCE_BIAS = RS::LIGHT_PARAM_TRANSMITTANCE_BIAS, PARAM_MAX = RS::LIGHT_PARAM_MAX }; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 2d004baf48..fa83428367 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -2871,6 +2871,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.color[2] = linear_col.b; light_data.specular = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR); + light_data.volumetric_fog_energy = light_storage->light_get_param(base, RS::LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY); light_data.mask = light_storage->light_get_cull_mask(base); float size = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE); @@ -2952,7 +2953,6 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const float fade_start = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_FADE_START); light_data.fade_from = -light_data.shadow_split_offsets[3] * MIN(fade_start, 0.999); //using 1.0 would break smoothstep light_data.fade_to = -light_data.shadow_split_offsets[3]; - light_data.shadow_volumetric_fog_fade = 1.0 / light_storage->light_get_shadow_volumetric_fog_fade(base); light_data.soft_shadow_scale = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR); light_data.softshadow_angle = angular_diameter; @@ -3082,6 +3082,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.color[1] = linear_col.g * energy; light_data.color[2] = linear_col.b * energy; light_data.specular_amount = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR) * 2.0; + light_data.volumetric_fog_energy = light_storage->light_get_param(base, RS::LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY); light_data.bake_mode = light_storage->light_get_bake_mode(base); float radius = MAX(0.001, light_storage->light_get_param(base, RS::LIGHT_PARAM_RANGE)); @@ -3176,7 +3177,6 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.atlas_rect[3] = rect.size.height; light_data.soft_shadow_scale = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR); - light_data.shadow_volumetric_fog_fade = 1.0 / light_storage->light_get_shadow_volumetric_fog_fade(base); if (type == RS::LIGHT_OMNI) { Transform3D proj = (inverse_transform * light_transform).inverse(); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 8e59b21aa8..3867fd8605 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -618,7 +618,7 @@ private: float soft_shadow_size; float soft_shadow_scale; uint32_t mask; - float shadow_volumetric_fog_fade; + float volumetric_fog_energy; uint32_t bake_mode; float projector_rect[4]; }; @@ -638,7 +638,7 @@ private: float fade_to; uint32_t pad[2]; uint32_t bake_mode; - float shadow_volumetric_fog_fade; + float volumetric_fog_energy; float shadow_bias[4]; float shadow_normal_bias[4]; float shadow_transmittance_bias[4]; diff --git a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl index 6f79b9e771..07d5223472 100644 --- a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl @@ -270,6 +270,9 @@ const vec3 halton_map[TEMPORAL_FRAMES] = vec3[]( vec3(0.9375, 0.25925926, 0.12), vec3(0.03125, 0.59259259, 0.32)); +// Higher values will make light in volumetric fog fade out sooner when it's occluded by shadow. +const float INV_FOG_FADE = 10.0; + void main() { vec3 fog_cell_size = 1.0 / vec3(params.fog_volume_size); @@ -375,46 +378,48 @@ void main() { if (total_density > 0.001) { for (uint i = 0; i < params.directional_light_count; i++) { - vec3 shadow_attenuation = vec3(1.0); - - if (directional_lights.data[i].shadow_opacity > 0.001) { - float depth_z = -view_pos.z; - - vec4 pssm_coord; - vec3 light_dir = directional_lights.data[i].direction; - vec4 v = vec4(view_pos, 1.0); - float z_range; - - if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { - pssm_coord = (directional_lights.data[i].shadow_matrix1 * v); - pssm_coord /= pssm_coord.w; - z_range = directional_lights.data[i].shadow_z_range.x; - - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { - pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); - pssm_coord /= pssm_coord.w; - z_range = directional_lights.data[i].shadow_z_range.y; - - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { - pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); - pssm_coord /= pssm_coord.w; - z_range = directional_lights.data[i].shadow_z_range.z; - - } else { - pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); - pssm_coord /= pssm_coord.w; - z_range = directional_lights.data[i].shadow_z_range.w; - } + if (directional_lights.data[i].volumetric_fog_energy > 0.001) { + vec3 shadow_attenuation = vec3(1.0); + + if (directional_lights.data[i].shadow_opacity > 0.001) { + float depth_z = -view_pos.z; + + vec4 pssm_coord; + vec3 light_dir = directional_lights.data[i].direction; + vec4 v = vec4(view_pos, 1.0); + float z_range; + + if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { + pssm_coord = (directional_lights.data[i].shadow_matrix1 * v); + pssm_coord /= pssm_coord.w; + z_range = directional_lights.data[i].shadow_z_range.x; + + } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { + pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); + pssm_coord /= pssm_coord.w; + z_range = directional_lights.data[i].shadow_z_range.y; + + } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { + pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); + pssm_coord /= pssm_coord.w; + z_range = directional_lights.data[i].shadow_z_range.z; + + } else { + pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); + pssm_coord /= pssm_coord.w; + z_range = directional_lights.data[i].shadow_z_range.w; + } - float depth = texture(sampler2D(directional_shadow_atlas, linear_sampler), pssm_coord.xy).r; - float shadow = exp(min(0.0, (depth - pssm_coord.z)) * z_range * directional_lights.data[i].shadow_volumetric_fog_fade); + float depth = texture(sampler2D(directional_shadow_atlas, linear_sampler), pssm_coord.xy).r; + float shadow = exp(min(0.0, (depth - pssm_coord.z)) * z_range * INV_FOG_FADE); - shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, view_pos.z)); //done with negative values for performance + shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, view_pos.z)); //done with negative values for performance - shadow_attenuation = mix(vec3(0.0), vec3(1.0), shadow); - } + shadow_attenuation = mix(vec3(1.0 - directional_lights.data[i].shadow_opacity), vec3(1.0), shadow); + } - total_light += shadow_attenuation * directional_lights.data[i].color * directional_lights.data[i].energy * henyey_greenstein(dot(normalize(view_pos), normalize(directional_lights.data[i].direction)), params.phase_g); + total_light += shadow_attenuation * directional_lights.data[i].color * directional_lights.data[i].energy * henyey_greenstein(dot(normalize(view_pos), normalize(directional_lights.data[i].direction)), params.phase_g) * directional_lights.data[i].volumetric_fog_energy; + } } // Compute light from sky @@ -481,7 +486,7 @@ void main() { float d = distance(omni_lights.data[light_index].position, view_pos); float shadow_attenuation = 1.0; - if (d * omni_lights.data[light_index].inv_radius < 1.0) { + if (omni_lights.data[light_index].volumetric_fog_energy > 0.001 && d * omni_lights.data[light_index].inv_radius < 1.0) { float attenuation = get_omni_attenuation(d, omni_lights.data[light_index].inv_radius, omni_lights.data[light_index].attenuation); vec3 light = omni_lights.data[light_index].color; @@ -509,9 +514,9 @@ void main() { float depth = texture(sampler2D(shadow_atlas, linear_sampler), pos.xy).r; - shadow_attenuation = exp(min(0.0, (depth - pos.z)) / omni_lights.data[light_index].inv_radius * omni_lights.data[light_index].shadow_volumetric_fog_fade); + shadow_attenuation = mix(1.0 - omni_lights.data[light_index].shadow_opacity, 1.0, exp(min(0.0, (depth - pos.z)) / omni_lights.data[light_index].inv_radius * INV_FOG_FADE)); } - total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_pos - view_pos), normalize(view_pos)), params.phase_g); + total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_pos - view_pos), normalize(view_pos)), params.phase_g) * omni_lights.data[light_index].volumetric_fog_energy; } } } @@ -562,7 +567,7 @@ void main() { float d = length(light_rel_vec); float shadow_attenuation = 1.0; - if (d * spot_lights.data[light_index].inv_radius < 1.0) { + if (spot_lights.data[light_index].volumetric_fog_energy > 0.001 && d * spot_lights.data[light_index].inv_radius < 1.0) { float attenuation = get_omni_attenuation(d, spot_lights.data[light_index].inv_radius, spot_lights.data[light_index].attenuation); vec3 spot_dir = spot_lights.data[light_index].direction; @@ -595,9 +600,9 @@ void main() { float depth = texture(sampler2D(shadow_atlas, linear_sampler), pos.xy).r; - shadow_attenuation = exp(min(0.0, (depth - pos.z)) / spot_lights.data[light_index].inv_radius * spot_lights.data[light_index].shadow_volumetric_fog_fade); + shadow_attenuation = mix(1.0 - spot_lights.data[light_index].shadow_opacity, 1.0, exp(min(0.0, (depth - pos.z)) / spot_lights.data[light_index].inv_radius * INV_FOG_FADE)); } - total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_rel_vec), normalize(view_pos)), params.phase_g); + total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_rel_vec), normalize(view_pos)), params.phase_g) * spot_lights.data[light_index].volumetric_fog_energy; } } } diff --git a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl index 799f7087b6..a7fca25a6b 100644 --- a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl @@ -25,7 +25,7 @@ struct LightData { //this structure needs to be as packed as possible highp float soft_shadow_size; // for spot, it's the size in uv coordinates of the light, for omni it's the span angle highp float soft_shadow_scale; // scales the shadow kernel for blurrier shadows uint mask; - mediump float shadow_volumetric_fog_fade; + mediump float volumetric_fog_energy; uint bake_mode; highp vec4 projector_rect; //projector rect in srgb decal atlas }; @@ -65,7 +65,7 @@ struct DirectionalLightData { highp float fade_to; uvec2 pad; uint bake_mode; - mediump float shadow_volumetric_fog_fade; + mediump float volumetric_fog_energy; highp vec4 shadow_bias; highp vec4 shadow_normal_bias; highp vec4 shadow_transmittance_bias; diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp index 7b58cc08dd..b845c1155e 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp @@ -75,6 +75,7 @@ void LightStorage::_light_initialize(RID p_light, RS::LightType p_type) { light.param[RS::LIGHT_PARAM_ENERGY] = 1.0; light.param[RS::LIGHT_PARAM_INDIRECT_ENERGY] = 1.0; + light.param[RS::LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY] = 1.0; light.param[RS::LIGHT_PARAM_SPECULAR] = 0.5; light.param[RS::LIGHT_PARAM_RANGE] = 1.0; light.param[RS::LIGHT_PARAM_SIZE] = 0.0; @@ -91,7 +92,6 @@ void LightStorage::_light_initialize(RID p_light, RS::LightType p_type) { light.param[RS::LIGHT_PARAM_SHADOW_OPACITY] = 1.0; light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0; light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0; - light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 0.1; light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05; light_owner.initialize_rid(p_light, light); diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.h b/servers/rendering/renderer_rd/storage_rd/light_storage.h index 3e3246e8e9..7e98a3cb8e 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.h @@ -250,13 +250,6 @@ public: return light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS]; } - _FORCE_INLINE_ float light_get_shadow_volumetric_fog_fade(RID p_light) const { - const Light *light = light_owner.get_or_null(p_light); - ERR_FAIL_COND_V(!light, 0.0); - - return light->param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE]; - } - virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override; virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override; virtual uint64_t light_get_version(RID p_light) const override; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 3e850a9798..88c20914e1 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1898,6 +1898,7 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(LIGHT_PARAM_ENERGY); BIND_ENUM_CONSTANT(LIGHT_PARAM_INDIRECT_ENERGY); + BIND_ENUM_CONSTANT(LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY); BIND_ENUM_CONSTANT(LIGHT_PARAM_SPECULAR); BIND_ENUM_CONSTANT(LIGHT_PARAM_RANGE); BIND_ENUM_CONSTANT(LIGHT_PARAM_SIZE); @@ -1914,7 +1915,6 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_PANCAKE_SIZE); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_OPACITY); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BLUR); - BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE); BIND_ENUM_CONSTANT(LIGHT_PARAM_TRANSMITTANCE_BIAS); BIND_ENUM_CONSTANT(LIGHT_PARAM_MAX); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index efa8a24325..3feec448e4 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -416,6 +416,7 @@ public: enum LightParam { LIGHT_PARAM_ENERGY, LIGHT_PARAM_INDIRECT_ENERGY, + LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY, LIGHT_PARAM_SPECULAR, LIGHT_PARAM_RANGE, LIGHT_PARAM_SIZE, @@ -432,7 +433,6 @@ public: LIGHT_PARAM_SHADOW_PANCAKE_SIZE, LIGHT_PARAM_SHADOW_OPACITY, LIGHT_PARAM_SHADOW_BLUR, - LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE, LIGHT_PARAM_TRANSMITTANCE_BIAS, LIGHT_PARAM_MAX }; |