Add a per-light volumetric fog energy property
Per-light energy gives more control to the user on the final result of volumetric fog. Specific lights can be fully excluded from volumetric fog by setting their volumetric fog energy to 0, which improves performance slightly. This can also be used to prevent short-lived dynamic effects from poorly interacting with volumetric fog, as it's updated over several frames by default unless temporal reprojection is disabled. Volumetric fog shadows now obey Light3D's Shadow Opacity property as well. The shadow fog fade property was removed as it had little visible impact on the final scene's rendering.
This commit is contained in:
parent
e27b61d291
commit
09bedcead4
14 changed files with 100 additions and 106 deletions
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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].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;
|
||||
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;
|
||||
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;
|
||||
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.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 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;
|
||||
} 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 * 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_attenuation = mix(vec3(1.0 - directional_lights.data[i].shadow_opacity), vec3(1.0), shadow);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue