Skip to content

Commit d7942ba

Browse files
committed
Automatically increase Light3D shadow bias when shadow blur is above 1.0
This makes it possible to adjust shadow blur without having to tweak bias to avoid shadow acne. The formula automatically increases shadow bias, normal bias and transmittance bias when shadow blur is above 1.0: shadow_blur_bias_factor = max(1, 0.5 + shadow_blur * 0.5); At the highest shadow blur value allowed in the inspector (8), the shadow bias and normal bias will each be multiplied by 5.5. Automatic adjustment is not performed for PCSS-style shadow blur (light size > 0) yet.
1 parent 7f18149 commit d7942ba

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

servers/rendering/renderer_rd/renderer_scene_render_rd.cpp

+20-8
Original file line numberDiff line numberDiff line change
@@ -3367,9 +3367,15 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
33673367

33683368
CameraMatrix shadow_mtx = rectm * bias * matrix * modelview;
33693369
light_data.shadow_split_offsets[j] = split;
3370-
float bias_scale = li->shadow_transform[j].bias_scale;
3370+
3371+
// If shadow blur is set above 1.0, scale the bias scale and normal bias with shadow blur to avoid shadow acne.
3372+
// At shadow blur = 8 (the highest value exposed in the inspector), the blur factor will be 5.5.
3373+
// This may still require further adjustments by the user, but this provides a good automatic baseline.
3374+
const float shadow_blur_bias_factor = MAX(1, 0.5 + light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR) * 0.5);
3375+
3376+
const float bias_scale = li->shadow_transform[j].bias_scale * shadow_blur_bias_factor;
33713377
light_data.shadow_bias[j] = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0 * bias_scale;
3372-
light_data.shadow_normal_bias[j] = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * li->shadow_transform[j].shadow_texel_size;
3378+
light_data.shadow_normal_bias[j] = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * li->shadow_transform[j].shadow_texel_size * shadow_blur_bias_factor;
33733379
light_data.shadow_transmittance_bias[j] = light_storage->light_get_transmittance_bias(base) * bias_scale;
33743380
light_data.shadow_z_range[j] = li->shadow_transform[j].farplane;
33753381
light_data.shadow_range_begin[j] = li->shadow_transform[j].range_begin;
@@ -3593,16 +3599,22 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
35933599

35943600
light_data.shadow_enabled = true;
35953601

3596-
float shadow_texel_size = light_instance_get_shadow_texel_size(li->self, p_shadow_atlas);
3597-
light_data.shadow_normal_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 10.0;
3602+
const float shadow_texel_size = light_instance_get_shadow_texel_size(li->self, p_shadow_atlas);
3603+
3604+
// If shadow blur is set above 1.0, scale the bias scale and normal bias with shadow blur to avoid shadow acne.
3605+
// At shadow blur = 8 (the highest value exposed in the inspector), the blur factor will be 5.5.
3606+
// This may still require further adjustments by the user, but this provides a good automatic baseline.
3607+
const float shadow_blur_bias_factor = MAX(1, 0.5 + light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR) * 0.5);
3608+
3609+
light_data.shadow_normal_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 10.0 * shadow_blur_bias_factor;
35983610

35993611
if (type == RS::LIGHT_SPOT) {
3600-
light_data.shadow_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0;
3601-
} else { //omni
3602-
light_data.shadow_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS);
3612+
light_data.shadow_bias = (light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0) * shadow_blur_bias_factor;
3613+
} else { // OmniLight3D
3614+
light_data.shadow_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * shadow_blur_bias_factor;
36033615
}
36043616

3605-
light_data.transmittance_bias = light_storage->light_get_transmittance_bias(base);
3617+
light_data.transmittance_bias = light_storage->light_get_transmittance_bias(base) * shadow_blur_bias_factor;
36063618

36073619
Vector2i omni_offset;
36083620
Rect2 rect = light_instance_get_shadow_atlas_rect(li->self, p_shadow_atlas, omni_offset);

0 commit comments

Comments
 (0)