Fix default shadow depth bias values and control them based on shadow resolution/quality mix

This commit is contained in:
2026-05-06 12:39:15 +02:00
parent 9a85ae7142
commit 9c5daf419b
7 changed files with 86 additions and 9 deletions
@@ -820,7 +820,7 @@ VkSampler* HelperResourcesVulkan::GetStaticSamplers()
RenderToolsVulkan::ZeroStruct(createInfo, VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
createInfo.mipLodBias = 0.0f;
createInfo.minLod = 0.0f;
createInfo.maxLod = MAX_float;
createInfo.maxLod = 1000.0f;
createInfo.maxAnisotropy = 1.0f;
createInfo.anisotropyEnable = VK_FALSE;
createInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
@@ -10,6 +10,8 @@
DirectionalLight::DirectionalLight(const SpawnParams& params)
: LightWithShadow(params)
{
ShadowsDepthBias = 0.002f;
_drawNoCulling = 1;
Brightness = 8.0f;
}
+1 -1
View File
@@ -151,7 +151,7 @@ public:
/// The depth bias used for shadow map comparison.
/// </summary>
API_FIELD(Attributes="EditorOrder(95), EditorDisplay(\"Shadow\", \"Depth Bias\"), Limit(0.0f, 10.0f, 0.0001f)")
float ShadowsDepthBias = 0.005f;
float ShadowsDepthBias = 0.05f;
/// <summary>
/// A factor specifying the offset to add to the calculated shadow map depth with respect to the surface normal.
+3 -2
View File
@@ -15,8 +15,9 @@ PointLight::PointLight(const SpawnParams& params)
{
CastVolumetricShadow = false;
ShadowsDistance = 2000.0f;
ShadowsFadeDistance = 100.0f;
ShadowsDepthBias = 0.5f;
ShadowsFadeDistance = 500.0f;
ShadowsDepthBias = 0.05f;
_direction = Float3::Forward;
_sphere = BoundingSphere(Vector3::Zero, _radius);
BoundingBox::FromSphere(_sphere, _box);
+2 -2
View File
@@ -19,8 +19,8 @@ SpotLight::SpotLight(const SpawnParams& params)
{
CastVolumetricShadow = false;
ShadowsDistance = 2000.0f;
ShadowsFadeDistance = 100.0f;
ShadowsDepthBias = 0.5f;
ShadowsFadeDistance = 500.0f;
ShadowsDepthBias = 0.05f;
_direction = Vector3::Forward;
_cosOuterCone = Math::Cos(_outerConeAngle * DegreesToRadians);
+74 -3
View File
@@ -635,9 +635,80 @@ void ShadowsPass::SetupLight(ShadowsCustomBuffer& shadows, RenderContext& render
atlasLight.Bounds.Center = light.Position + renderContext.View.Origin; // Keep bounds in world-space to properly handle DirtyStaticBounds
atlasLight.Bounds.Radius = 0.0f;
// Adjust bias to account for lower shadow quality
if (shadows.MaxShadowsQuality == 0)
atlasLight.Bias *= 1.5f;
// Adjust bias to account for lower shadow quality (mix between different shadow map resolution and filter size) to automatically hide artifacts
switch ((Quality)shadows.MaxShadowsQuality)
{
case Quality::Low:
switch (Graphics::ShadowMapsQuality)
{
case Quality::Low:
atlasLight.Bias += 0.003f;
break;
case Quality::Medium:
atlasLight.Bias += 0.001f;
break;
}
break;
case Quality::Medium:
switch (Graphics::ShadowMapsQuality)
{
case Quality::Low:
atlasLight.Bias += 0.008f;
break;
case Quality::Medium:
atlasLight.Bias += 0.003f;
break;
case Quality::High:
atlasLight.Bias += 0.001f;
break;
}
break;
case Quality::High:
switch (Graphics::ShadowMapsQuality)
{
case Quality::Low:
atlasLight.Bias += 0.012f;
break;
case Quality::Medium:
atlasLight.Bias += 0.006f;
break;
case Quality::High:
atlasLight.Bias += 0.002f;
break;
}
break;
}
if (!light.IsDirectionalLight)
{
switch ((Quality)shadows.MaxShadowsQuality)
{
case Quality::Medium:
switch (Graphics::ShadowMapsQuality)
{
case Quality::Low:
atlasLight.NormalOffsetScale += 25;
break;
case Quality::Medium:
atlasLight.NormalOffsetScale += 10;
break;
}
break;
case Quality::High:
switch (Graphics::ShadowMapsQuality)
{
case Quality::Low:
atlasLight.NormalOffsetScale += 20;
break;
case Quality::Medium:
atlasLight.NormalOffsetScale +=15;
break;
case Quality::High:
atlasLight.NormalOffsetScale += 5;
break;
}
break;
}
}
}
bool ShadowsPass::SetupLight(ShadowsCustomBuffer& shadows, RenderContext& renderContext, RenderContextBatch& renderContextBatch, RenderLocalLightData& light, ShadowAtlasLight& atlasLight)
+3
View File
@@ -334,6 +334,9 @@ float SampleShadowMapPCSS(Texture2D<float> shadowMap, float2 shadowMapUV, float
// Calculate penumbra size
float penumbra = max(sceneDepth - avgBlockerDistance, 0.0);
#if defined(VULKAN)
sceneDepth *= lerp(1, 0.985f, saturate(penumbra * 4.0f)); // Fix shadow bias issues on Vulkan
#endif
float filterRadius = penumbra * sourceAngle;
filterRadius = max(filterRadius, minRadius); // Don't use too small filter near blockers to avoid jagged edges