rendering: formalize main light shadow bias settings

This commit is contained in:
2026-04-13 01:40:29 +08:00
parent 2ee74e7761
commit 1d6f2e290d
11 changed files with 113 additions and 26 deletions

View File

@@ -44,7 +44,8 @@ struct MockPipelineState {
bool lastHasMainDirectionalShadow = false;
XCEngine::RHI::RHIResourceView* lastShadowMap = nullptr;
XCEngine::Math::Matrix4x4 lastShadowViewProjection = XCEngine::Math::Matrix4x4::Identity();
XCEngine::Math::Vector4 lastShadowParams = XCEngine::Math::Vector4::Zero();
RenderDirectionalShadowMapMetrics lastShadowMapMetrics = {};
RenderDirectionalShadowSamplingData lastShadowSampling = {};
bool lastHasMainDirectionalShadowKeyword = false;
RenderEnvironmentMode lastEnvironmentMode = RenderEnvironmentMode::None;
bool lastHasSkybox = false;
@@ -327,7 +328,8 @@ public:
m_state->lastHasMainDirectionalShadow = sceneData.lighting.HasMainDirectionalShadow();
m_state->lastShadowMap = sceneData.lighting.mainDirectionalShadow.shadowMap;
m_state->lastShadowViewProjection = sceneData.lighting.mainDirectionalShadow.viewProjection;
m_state->lastShadowParams = sceneData.lighting.mainDirectionalShadow.shadowParams;
m_state->lastShadowMapMetrics = sceneData.lighting.mainDirectionalShadow.mapMetrics;
m_state->lastShadowSampling = sceneData.lighting.mainDirectionalShadow.sampling;
m_state->lastHasMainDirectionalShadowKeyword =
XCEngine::Resources::ShaderKeywordSetContains(
sceneData.globalShaderKeywords,
@@ -1338,10 +1340,10 @@ TEST(CameraRenderer_Test, AutoAllocatesDirectionalShadowSurfaceFromShadowPlan) {
EXPECT_FLOAT_EQ(pipelineState->lastShadowViewProjection.m[0][3], 11.0f);
EXPECT_FLOAT_EQ(pipelineState->lastShadowViewProjection.m[1][3], 12.0f);
EXPECT_FLOAT_EQ(pipelineState->lastShadowViewProjection.m[2][3], 13.0f);
EXPECT_FLOAT_EQ(pipelineState->lastShadowParams.x, 0.0015f);
EXPECT_FLOAT_EQ(pipelineState->lastShadowParams.y, 1.0f / 256.0f);
EXPECT_FLOAT_EQ(pipelineState->lastShadowParams.z, 1.0f / 128.0f);
EXPECT_FLOAT_EQ(pipelineState->lastShadowParams.w, 0.85f);
EXPECT_FLOAT_EQ(pipelineState->lastShadowSampling.settings.receiverDepthBias, 0.0015f);
EXPECT_FLOAT_EQ(pipelineState->lastShadowMapMetrics.inverseMapSize.x, 1.0f / 256.0f);
EXPECT_FLOAT_EQ(pipelineState->lastShadowMapMetrics.inverseMapSize.y, 1.0f / 128.0f);
EXPECT_FLOAT_EQ(pipelineState->lastShadowSampling.settings.shadowStrength, 0.85f);
EXPECT_TRUE(pipelineState->lastHasMainDirectionalShadowKeyword);
}

View File

@@ -224,6 +224,11 @@ TEST(SceneRenderRequestPlanner_Test, AppliesConfiguredDirectionalShadowPlanningS
settings.maxFocusDistance = 12.0f;
settings.perspectiveFocusFactor = 0.01f;
settings.minDepthRange = 80.0f;
settings.sampling.receiverDepthBias = 0.0025f;
settings.sampling.normalBiasScale = 2.0f;
settings.sampling.shadowStrength = 0.75f;
settings.casterBias.depthBiasFactor = 2.5f;
settings.casterBias.depthBiasUnits = 4;
planner.SetDirectionalShadowPlanningSettings(settings);
const std::vector<CameraRenderRequest> requests = planner.BuildRequests(
@@ -241,6 +246,11 @@ TEST(SceneRenderRequestPlanner_Test, AppliesConfiguredDirectionalShadowPlanningS
EXPECT_EQ(request.shadowCaster.cameraDataOverride.viewportHeight, 2048u);
EXPECT_GE(request.directionalShadow.focusPoint.z, 6.0f);
EXPECT_LE(request.directionalShadow.focusPoint.z, 6.3f);
EXPECT_FLOAT_EQ(request.directionalShadow.sampling.receiverDepthBias, 0.0025f);
EXPECT_FLOAT_EQ(request.directionalShadow.sampling.normalBiasScale, 2.0f);
EXPECT_FLOAT_EQ(request.directionalShadow.sampling.shadowStrength, 0.75f);
EXPECT_FLOAT_EQ(request.directionalShadow.casterBias.depthBiasFactor, 2.5f);
EXPECT_EQ(request.directionalShadow.casterBias.depthBiasUnits, 4);
EXPECT_GE(
request.directionalShadow.farClipPlane - request.directionalShadow.nearClipPlane,
80.0f);
@@ -258,6 +268,11 @@ TEST(SceneRenderRequestPlanner_Test, SanitizesInvalidDirectionalShadowPlanningSe
invalidSettings.minDepthRange = 0.0f;
invalidSettings.boundsPadding = -1.0f;
invalidSettings.minDepthPadding = -3.0f;
invalidSettings.sampling.receiverDepthBias = -0.5f;
invalidSettings.sampling.normalBiasScale = -2.0f;
invalidSettings.sampling.shadowStrength = 3.0f;
invalidSettings.casterBias.depthBiasFactor = -1.0f;
invalidSettings.casterBias.depthBiasUnits = -6;
planner.SetDirectionalShadowPlanningSettings(invalidSettings);
const DirectionalShadowPlanningSettings& settings =
@@ -270,4 +285,9 @@ TEST(SceneRenderRequestPlanner_Test, SanitizesInvalidDirectionalShadowPlanningSe
EXPECT_FLOAT_EQ(settings.minDepthRange, 20.0f);
EXPECT_FLOAT_EQ(settings.boundsPadding, 1.0f);
EXPECT_FLOAT_EQ(settings.minDepthPadding, 2.0f);
EXPECT_FLOAT_EQ(settings.sampling.receiverDepthBias, 0.0015f);
EXPECT_FLOAT_EQ(settings.sampling.normalBiasScale, 1.5f);
EXPECT_FLOAT_EQ(settings.sampling.shadowStrength, 1.0f);
EXPECT_FLOAT_EQ(settings.casterBias.depthBiasFactor, 1.0f);
EXPECT_EQ(settings.casterBias.depthBiasUnits, 2);
}