@@ -3272,6 +3272,11 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
3272
3272
3273
3273
r_directional_light_soft_shadows = false ;
3274
3274
3275
+ ShadowAtlas *shadow_atlas = nullptr ;
3276
+ if (p_shadow_atlas.is_valid () && p_using_shadows) {
3277
+ shadow_atlas = shadow_atlas_owner.get_or_null (p_shadow_atlas);
3278
+ }
3279
+
3275
3280
for (int i = 0 ; i < (int )p_lights.size (); i++) {
3276
3281
LightInstance *li = light_instance_owner.get_or_null (p_lights[i]);
3277
3282
if (!li) {
@@ -3419,9 +3424,19 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
3419
3424
Transform3D modelview = (inverse_transform * li->shadow_transform [j].transform ).inverse ();
3420
3425
3421
3426
CameraMatrix shadow_mtx = rectm * bias * matrix * modelview;
3427
+
3422
3428
light_data.shadow_split_offsets [j] = split;
3423
- float bias_scale = li->shadow_transform [j].bias_scale ;
3424
- light_data.shadow_bias [j] = storage->light_get_param (base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0 * bias_scale;
3429
+
3430
+ float bias_scale;
3431
+ if (directional_shadow.size < 4096 ) {
3432
+ // For shadow map sizes below the default, don't increase bias too much to avoid peter-panning.
3433
+ bias_scale = (1 + li->shadow_transform [j].bias_scale * (4096.0 / MAX (256 , directional_shadow.size ))) * 0.5 ;
3434
+ } else {
3435
+ // Reduce shadow bias for shadow map sizes higher than the default.
3436
+ bias_scale = li->shadow_transform [j].bias_scale * (4096.0 / directional_shadow.size );
3437
+ }
3438
+
3439
+ light_data.shadow_bias [j] = (storage->light_get_param (base, RS::LIGHT_PARAM_SHADOW_BIAS) * bias_scale) / 100.0 ;
3425
3440
light_data.shadow_normal_bias [j] = storage->light_get_param (base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * li->shadow_transform [j].shadow_texel_size ;
3426
3441
light_data.shadow_transmittance_bias [j] = storage->light_get_transmittance_bias (base) * bias_scale;
3427
3442
light_data.shadow_z_range [j] = li->shadow_transform [j].farplane ;
@@ -3499,12 +3514,6 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
3499
3514
sorter.sort (cluster.spot_light_sort , cluster.spot_light_count );
3500
3515
}
3501
3516
3502
- ShadowAtlas *shadow_atlas = nullptr ;
3503
-
3504
- if (p_shadow_atlas.is_valid () && p_using_shadows) {
3505
- shadow_atlas = shadow_atlas_owner.get_or_null (p_shadow_atlas);
3506
- }
3507
-
3508
3517
bool using_forward_ids = _uses_forward_ids ();
3509
3518
3510
3519
for (uint32_t i = 0 ; i < (cluster.omni_light_count + cluster.spot_light_count ); i++) {
@@ -3594,13 +3603,22 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
3594
3603
float shadow_texel_size = light_instance_get_shadow_texel_size (li->self , p_shadow_atlas);
3595
3604
light_data.shadow_normal_bias = storage->light_get_param (base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 10.0 ;
3596
3605
3606
+ float bias_resolution_factor;
3607
+ if (shadow_atlas->size < 4096 ) {
3608
+ // For shadow map sizes below the default, don't increase bias too much to avoid peter-panning.
3609
+ bias_resolution_factor = (1 + (4096.0 / MAX (256 , shadow_atlas->size ))) * 0.5 ;
3610
+ } else {
3611
+ // Reduce shadow bias for shadow map sizes higher than the default.
3612
+ bias_resolution_factor = (4096.0 / shadow_atlas->size );
3613
+ }
3614
+
3597
3615
if (type == RS::LIGHT_SPOT) {
3598
- light_data.shadow_bias = storage->light_get_param (base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0 ;
3616
+ light_data.shadow_bias = ( storage->light_get_param (base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0 ) * bias_resolution_factor ;
3599
3617
} else { // omni
3600
- light_data.shadow_bias = storage->light_get_param (base, RS::LIGHT_PARAM_SHADOW_BIAS);
3618
+ light_data.shadow_bias = storage->light_get_param (base, RS::LIGHT_PARAM_SHADOW_BIAS) * bias_resolution_factor ;
3601
3619
}
3602
3620
3603
- light_data.transmittance_bias = storage->light_get_transmittance_bias (base);
3621
+ light_data.transmittance_bias = storage->light_get_transmittance_bias (base) * bias_resolution_factor ;
3604
3622
3605
3623
Vector2i omni_offset;
3606
3624
Rect2 rect = light_instance_get_shadow_atlas_rect (li->self , p_shadow_atlas, omni_offset);
0 commit comments