refactor(rendering): move directional shadow execution defaults into pipeline
This commit is contained in:
@@ -51,6 +51,7 @@ struct MockPipelineState {
|
||||
int initializeCalls = 0;
|
||||
int shutdownCalls = 0;
|
||||
int configureRenderSceneDataCalls = 0;
|
||||
int configureDirectionalShadowExecutionStateCalls = 0;
|
||||
int renderCalls = 0;
|
||||
int recordMainSceneCalls = 0;
|
||||
int executeRecordedMainSceneCalls = 0;
|
||||
@@ -86,6 +87,10 @@ struct MockPipelineState {
|
||||
bool lastBlackboardMainDirectionalShadowValid = false;
|
||||
bool lastBlackboardObjectIdColorValid = false;
|
||||
std::function<void(const CameraFramePlan&, RenderSceneData&)> configureRenderSceneData = {};
|
||||
std::function<bool(
|
||||
const CameraFramePlan&,
|
||||
const DirectionalShadowSurfaceAllocation&,
|
||||
DirectionalShadowExecutionState&)> configureDirectionalShadowExecutionState = {};
|
||||
std::vector<CameraComponent*> renderedCameras;
|
||||
std::vector<RenderClearFlags> renderedClearFlags;
|
||||
std::vector<XCEngine::Math::Color> renderedClearColors;
|
||||
@@ -453,6 +458,24 @@ public:
|
||||
RenderPipeline::ConfigureRenderSceneData(plan, sceneData);
|
||||
}
|
||||
|
||||
bool ConfigureDirectionalShadowExecutionState(
|
||||
const CameraFramePlan& plan,
|
||||
const DirectionalShadowSurfaceAllocation& shadowAllocation,
|
||||
DirectionalShadowExecutionState& shadowState) const override {
|
||||
++m_state->configureDirectionalShadowExecutionStateCalls;
|
||||
if (m_state->configureDirectionalShadowExecutionState) {
|
||||
return m_state->configureDirectionalShadowExecutionState(
|
||||
plan,
|
||||
shadowAllocation,
|
||||
shadowState);
|
||||
}
|
||||
|
||||
return RenderPipeline::ConfigureDirectionalShadowExecutionState(
|
||||
plan,
|
||||
shadowAllocation,
|
||||
shadowState);
|
||||
}
|
||||
|
||||
void Shutdown() override {
|
||||
++m_state->shutdownCalls;
|
||||
ShutdownCameraFrameStandalonePasses();
|
||||
@@ -2399,6 +2422,88 @@ TEST(CameraRenderer_Test, AutoAllocatesDirectionalShadowSurfaceFromShadowPlan) {
|
||||
EXPECT_EQ(allocationState->destroyTextureCalls, 1);
|
||||
}
|
||||
|
||||
TEST(CameraRenderer_Test, AllowsPipelineToOverrideAutoAllocatedDirectionalShadowExecutionState) {
|
||||
Scene scene("CameraRendererDirectionalShadowExecutionPolicyScene");
|
||||
|
||||
GameObject* cameraObject = scene.CreateGameObject("Camera");
|
||||
auto* camera = cameraObject->AddComponent<CameraComponent>();
|
||||
camera->SetPrimary(true);
|
||||
camera->SetDepth(2.0f);
|
||||
|
||||
auto pipelineState = std::make_shared<MockPipelineState>();
|
||||
pipelineState->configureDirectionalShadowExecutionState =
|
||||
[](
|
||||
const CameraFramePlan& plan,
|
||||
const DirectionalShadowSurfaceAllocation& shadowAllocation,
|
||||
DirectionalShadowExecutionState& shadowState) {
|
||||
ApplyDefaultRenderPipelineDirectionalShadowExecutionPolicy(
|
||||
plan,
|
||||
shadowAllocation,
|
||||
shadowState);
|
||||
shadowState.shadowCasterRequest.clearFlags = RenderClearFlags::All;
|
||||
shadowState.shadowCasterRequest.hasCameraDataOverride = true;
|
||||
shadowState.shadowCasterRequest.cameraDataOverride =
|
||||
plan.directionalShadow.cameraData;
|
||||
shadowState.shadowCasterRequest.cameraDataOverride.worldPosition =
|
||||
XCEngine::Math::Vector3(7.0f, 8.0f, 9.0f);
|
||||
shadowState.shadowData.sampling.settings.shadowStrength = 0.25f;
|
||||
return true;
|
||||
};
|
||||
auto allocationState = std::make_shared<MockShadowAllocationState>();
|
||||
MockShadowDevice device(allocationState);
|
||||
|
||||
RenderContext context = CreateValidContext();
|
||||
context.device = &device;
|
||||
|
||||
{
|
||||
auto pipeline = std::make_unique<MockPipeline>(pipelineState);
|
||||
InstallStandaloneStagePass<MockObjectIdPass>(
|
||||
*pipeline,
|
||||
CameraFrameStage::ObjectId,
|
||||
pipelineState);
|
||||
MockScenePass* shadowPassRaw =
|
||||
InstallStandaloneStagePass<MockScenePass>(
|
||||
*pipeline,
|
||||
CameraFrameStage::ShadowCaster,
|
||||
pipelineState,
|
||||
"shadowCaster");
|
||||
CameraRenderer renderer(std::move(pipeline));
|
||||
|
||||
CameraRenderRequest request;
|
||||
request.scene = &scene;
|
||||
request.camera = camera;
|
||||
request.context = context;
|
||||
request.surface = RenderSurface(320, 180);
|
||||
request.cameraDepth = camera->GetDepth();
|
||||
request.directionalShadow.enabled = true;
|
||||
request.directionalShadow.mapWidth = 256;
|
||||
request.directionalShadow.mapHeight = 128;
|
||||
request.directionalShadow.cameraData.viewportWidth = 256;
|
||||
request.directionalShadow.cameraData.viewportHeight = 128;
|
||||
request.directionalShadow.cameraData.clearFlags = RenderClearFlags::Depth;
|
||||
request.directionalShadow.cameraData.worldPosition =
|
||||
XCEngine::Math::Vector3(3.0f, 4.0f, 5.0f);
|
||||
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_EQ(
|
||||
pipelineState->eventLog,
|
||||
(std::vector<std::string>{
|
||||
"init:shadowCaster",
|
||||
"shadowCaster",
|
||||
"pipeline" }));
|
||||
EXPECT_EQ(
|
||||
pipelineState->configureDirectionalShadowExecutionStateCalls,
|
||||
1);
|
||||
EXPECT_EQ(shadowPassRaw->lastClearFlags, RenderClearFlags::All);
|
||||
EXPECT_EQ(
|
||||
shadowPassRaw->lastWorldPosition,
|
||||
XCEngine::Math::Vector3(7.0f, 8.0f, 9.0f));
|
||||
EXPECT_FLOAT_EQ(
|
||||
pipelineState->lastShadowSampling.settings.shadowStrength,
|
||||
0.25f);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CameraRenderer_Test, PassesShadowDependencyToPipelineRecordedMainScene) {
|
||||
Scene scene("CameraRendererPipelineRecordedShadowDependency");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user