@@ -3367,9 +3367,15 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
3367
3367
3368
3368
CameraMatrix shadow_mtx = rectm * bias * matrix * modelview;
3369
3369
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;
3371
3377
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 ;
3373
3379
light_data.shadow_transmittance_bias [j] = light_storage->light_get_transmittance_bias (base) * bias_scale;
3374
3380
light_data.shadow_z_range [j] = li->shadow_transform [j].farplane ;
3375
3381
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
3593
3599
3594
3600
light_data.shadow_enabled = true ;
3595
3601
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;
3598
3610
3599
3611
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 ;
3603
3615
}
3604
3616
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 ;
3606
3618
3607
3619
Vector2i omni_offset;
3608
3620
Rect2 rect = light_instance_get_shadow_atlas_rect (li->self , p_shadow_atlas, omni_offset);
0 commit comments