|
@@ -2869,7 +2869,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
|
|
WARN_PRINT_ONCE("The DirectionalLight3D PSSM splits debug draw mode is not reimplemented yet.");
|
|
WARN_PRINT_ONCE("The DirectionalLight3D PSSM splits debug draw mode is not reimplemented yet.");
|
|
}
|
|
}
|
|
|
|
|
|
- light_data.shadow_enabled = p_using_shadows && light_storage->light_has_shadow(base);
|
|
|
|
|
|
+ light_data.shadow_opacity = p_using_shadows && light_storage->light_has_shadow(base) ? light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_OPACITY) : 0.0;
|
|
|
|
|
|
float angular_diameter = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
|
|
float angular_diameter = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
|
|
if (angular_diameter > 0.0) {
|
|
if (angular_diameter > 0.0) {
|
|
@@ -2886,7 +2886,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
|
|
angular_diameter = 0.0;
|
|
angular_diameter = 0.0;
|
|
}
|
|
}
|
|
|
|
|
|
- if (light_data.shadow_enabled) {
|
|
|
|
|
|
+ if (light_data.shadow_opacity > 0.001) {
|
|
RS::LightDirectionalShadowMode smode = light_storage->light_directional_get_shadow_mode(base);
|
|
RS::LightDirectionalShadowMode smode = light_storage->light_directional_get_shadow_mode(base);
|
|
|
|
|
|
int limit = smode == RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ? 0 : (smode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS ? 1 : 3);
|
|
int limit = smode == RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ? 0 : (smode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS ? 1 : 3);
|
|
@@ -3040,19 +3040,26 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
|
|
|
|
|
|
// Reuse fade begin, fade length and distance for shadow LOD determination later.
|
|
// Reuse fade begin, fade length and distance for shadow LOD determination later.
|
|
float fade_begin = 0.0;
|
|
float fade_begin = 0.0;
|
|
|
|
+ float fade_shadow = 0.0;
|
|
float fade_length = 0.0;
|
|
float fade_length = 0.0;
|
|
real_t distance = 0.0;
|
|
real_t distance = 0.0;
|
|
|
|
|
|
float fade = 1.0;
|
|
float fade = 1.0;
|
|
|
|
+ float shadow_opacity_fade = 1.0;
|
|
if (light_storage->light_is_distance_fade_enabled(li->light)) {
|
|
if (light_storage->light_is_distance_fade_enabled(li->light)) {
|
|
fade_begin = light_storage->light_get_distance_fade_begin(li->light);
|
|
fade_begin = light_storage->light_get_distance_fade_begin(li->light);
|
|
|
|
+ fade_shadow = light_storage->light_get_distance_fade_shadow(li->light);
|
|
fade_length = light_storage->light_get_distance_fade_length(li->light);
|
|
fade_length = light_storage->light_get_distance_fade_length(li->light);
|
|
distance = camera_plane.distance_to(li->transform.origin);
|
|
distance = camera_plane.distance_to(li->transform.origin);
|
|
|
|
|
|
|
|
+ // Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player.
|
|
if (distance > fade_begin) {
|
|
if (distance > fade_begin) {
|
|
- // Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player.
|
|
|
|
fade = Math::smoothstep(0.0f, 1.0f, 1.0f - float(distance - fade_begin) / fade_length);
|
|
fade = Math::smoothstep(0.0f, 1.0f, 1.0f - float(distance - fade_begin) / fade_length);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (distance > fade_shadow) {
|
|
|
|
+ shadow_opacity_fade = Math::smoothstep(0.0f, 1.0f, 1.0f - float(distance - fade_shadow) / fade_length);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
float energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI * fade;
|
|
float energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI * fade;
|
|
@@ -3120,7 +3127,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
|
|
|
|
|
|
bool in_shadow_range = true;
|
|
bool in_shadow_range = true;
|
|
if (needs_shadow && light_storage->light_is_distance_fade_enabled(li->light)) {
|
|
if (needs_shadow && light_storage->light_is_distance_fade_enabled(li->light)) {
|
|
- if (distance > light_storage->light_get_distance_fade_shadow(li->light)) {
|
|
|
|
|
|
+ if (distance > light_storage->light_get_distance_fade_shadow(li->light) + light_storage->light_get_distance_fade_length(li->light)) {
|
|
// Out of range, don't draw shadows to improve performance.
|
|
// Out of range, don't draw shadows to improve performance.
|
|
in_shadow_range = false;
|
|
in_shadow_range = false;
|
|
}
|
|
}
|
|
@@ -3129,7 +3136,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
|
|
if (needs_shadow && in_shadow_range) {
|
|
if (needs_shadow && in_shadow_range) {
|
|
// fill in the shadow information
|
|
// fill in the shadow information
|
|
|
|
|
|
- light_data.shadow_enabled = true;
|
|
|
|
|
|
+ light_data.shadow_opacity = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_OPACITY) * shadow_opacity_fade;
|
|
|
|
|
|
float shadow_texel_size = light_instance_get_shadow_texel_size(li->self, p_shadow_atlas);
|
|
float shadow_texel_size = light_instance_get_shadow_texel_size(li->self, p_shadow_atlas);
|
|
light_data.shadow_normal_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 10.0;
|
|
light_data.shadow_normal_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 10.0;
|
|
@@ -3189,7 +3196,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- light_data.shadow_enabled = false;
|
|
|
|
|
|
+ light_data.shadow_opacity = 0.0;
|
|
}
|
|
}
|
|
|
|
|
|
li->cull_mask = light_storage->light_get_cull_mask(base);
|
|
li->cull_mask = light_storage->light_get_cull_mask(base);
|
|
@@ -3637,7 +3644,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
|
|
if (p_render_data->render_buffers.is_valid()) {
|
|
if (p_render_data->render_buffers.is_valid()) {
|
|
bool directional_shadows = false;
|
|
bool directional_shadows = false;
|
|
for (uint32_t i = 0; i < directional_light_count; i++) {
|
|
for (uint32_t i = 0; i < directional_light_count; i++) {
|
|
- if (cluster.directional_lights[i].shadow_enabled) {
|
|
|
|
|
|
+ if (cluster.directional_lights[i].shadow_opacity > 0.001) {
|
|
directional_shadows = true;
|
|
directional_shadows = true;
|
|
break;
|
|
break;
|
|
}
|
|
}
|