diff --git a/engine/include/XCEngine/Rendering/Pipelines/ScriptableRenderPipelineHost.h b/engine/include/XCEngine/Rendering/Pipelines/ScriptableRenderPipelineHost.h index 538adb21..8152aac2 100644 --- a/engine/include/XCEngine/Rendering/Pipelines/ScriptableRenderPipelineHost.h +++ b/engine/include/XCEngine/Rendering/Pipelines/ScriptableRenderPipelineHost.h @@ -69,6 +69,7 @@ public: std::shared_ptr pipelineRendererAsset); std::unique_ptr CreatePipeline() const override; + void ConfigurePipeline(RenderPipeline& pipeline) const override; FinalColorSettings GetDefaultFinalColorSettings() const override; private: diff --git a/engine/include/XCEngine/Rendering/RenderPipelineAsset.h b/engine/include/XCEngine/Rendering/RenderPipelineAsset.h index f5ce413f..3048a3d0 100644 --- a/engine/include/XCEngine/Rendering/RenderPipelineAsset.h +++ b/engine/include/XCEngine/Rendering/RenderPipelineAsset.h @@ -19,6 +19,7 @@ public: virtual ~RenderPipelineAsset() = default; virtual std::unique_ptr CreatePipeline() const = 0; + virtual void ConfigurePipeline(RenderPipeline&) const {} virtual FinalColorSettings GetDefaultFinalColorSettings() const { return {}; } virtual void ConfigureCameraFramePlan(CameraFramePlan& plan) const; }; diff --git a/engine/src/Rendering/Execution/CameraRenderer.cpp b/engine/src/Rendering/Execution/CameraRenderer.cpp index f7cc1753..4a90ec36 100644 --- a/engine/src/Rendering/Execution/CameraRenderer.cpp +++ b/engine/src/Rendering/Execution/CameraRenderer.cpp @@ -21,8 +21,20 @@ std::shared_ptr CreateDefaultPipelineAsset() { std::unique_ptr CreatePipelineFromAsset( const std::shared_ptr& pipelineAsset) { - if (pipelineAsset != nullptr) { - std::unique_ptr pipeline = pipelineAsset->CreatePipeline(); + const std::shared_ptr resolvedAsset = + pipelineAsset != nullptr ? pipelineAsset : CreateDefaultPipelineAsset(); + if (resolvedAsset != nullptr) { + std::unique_ptr pipeline = resolvedAsset->CreatePipeline(); + if (pipeline != nullptr) { + return pipeline; + } + } + + const std::shared_ptr fallbackAsset = + CreateDefaultPipelineAsset(); + if (fallbackAsset != nullptr && + fallbackAsset != resolvedAsset) { + std::unique_ptr pipeline = fallbackAsset->CreatePipeline(); if (pipeline != nullptr) { return pipeline; } diff --git a/engine/src/Rendering/Pipelines/ScriptableRenderPipelineHost.cpp b/engine/src/Rendering/Pipelines/ScriptableRenderPipelineHost.cpp index 0f3a2472..e90a9445 100644 --- a/engine/src/Rendering/Pipelines/ScriptableRenderPipelineHost.cpp +++ b/engine/src/Rendering/Pipelines/ScriptableRenderPipelineHost.cpp @@ -1,9 +1,9 @@ #include "Rendering/Pipelines/ScriptableRenderPipelineHost.h" +#include "Rendering/Pipelines/BuiltinForwardPipeline.h" #include "Rendering/Passes/BuiltinDepthOnlyPass.h" #include "Rendering/Passes/BuiltinObjectIdPass.h" #include "Rendering/Passes/BuiltinShadowCasterPass.h" -#include "Rendering/Pipelines/BuiltinForwardPipeline.h" namespace XCEngine { namespace Rendering { @@ -32,18 +32,6 @@ std::unique_ptr CreatePipelineRendererFromAsset( return std::make_unique(); } -void InstallDefaultStandaloneStagePasses(RenderPipeline& pipeline) { - pipeline.SetCameraFrameStandalonePass( - CameraFrameStage::ObjectId, - std::make_unique()); - pipeline.SetCameraFrameStandalonePass( - CameraFrameStage::DepthOnly, - std::make_unique()); - pipeline.SetCameraFrameStandalonePass( - CameraFrameStage::ShadowCaster, - std::make_unique()); -} - } // namespace ScriptableRenderPipelineHost::ScriptableRenderPipelineHost() @@ -52,7 +40,6 @@ ScriptableRenderPipelineHost::ScriptableRenderPipelineHost() ScriptableRenderPipelineHost::ScriptableRenderPipelineHost( std::unique_ptr pipelineRenderer) { - InstallDefaultStandaloneStagePasses(*this); ResetPipelineRenderer(std::move(pipelineRenderer)); } @@ -62,7 +49,6 @@ ScriptableRenderPipelineHost::ScriptableRenderPipelineHost( pipelineRendererAsset != nullptr ? std::move(pipelineRendererAsset) : CreateDefaultPipelineRendererAsset()) { - InstallDefaultStandaloneStagePasses(*this); ResetPipelineRenderer( CreatePipelineRendererFromAsset(m_pipelineRendererAsset)); } @@ -267,8 +253,27 @@ ScriptableRenderPipelineHostAsset::ScriptableRenderPipelineHostAsset( } std::unique_ptr ScriptableRenderPipelineHostAsset::CreatePipeline() const { - return std::make_unique( - m_pipelineRendererAsset); + std::unique_ptr pipeline = + std::make_unique( + m_pipelineRendererAsset); + if (pipeline != nullptr) { + ConfigurePipeline(*pipeline); + } + + return pipeline; +} + +void ScriptableRenderPipelineHostAsset::ConfigurePipeline( + RenderPipeline& pipeline) const { + pipeline.SetCameraFrameStandalonePass( + CameraFrameStage::ObjectId, + std::make_unique()); + pipeline.SetCameraFrameStandalonePass( + CameraFrameStage::DepthOnly, + std::make_unique()); + pipeline.SetCameraFrameStandalonePass( + CameraFrameStage::ShadowCaster, + std::make_unique()); } FinalColorSettings ScriptableRenderPipelineHostAsset::GetDefaultFinalColorSettings() const { diff --git a/tests/Rendering/unit/test_camera_scene_renderer.cpp b/tests/Rendering/unit/test_camera_scene_renderer.cpp index 3611e82f..a901a706 100644 --- a/tests/Rendering/unit/test_camera_scene_renderer.cpp +++ b/tests/Rendering/unit/test_camera_scene_renderer.cpp @@ -4076,6 +4076,16 @@ TEST(ScriptableRenderPipelineHost_Test, PrefersStageRecorderBeforeFallbackRender EXPECT_EQ(replacementRecorderState->shutdownCalls, 1); } +TEST(ScriptableRenderPipelineHost_Test, DirectHostDoesNotInstallBuiltinStandaloneStagePasses) { + auto rendererState = std::make_shared(); + Pipelines::ScriptableRenderPipelineHost host( + std::make_unique(rendererState)); + + EXPECT_EQ(host.GetCameraFrameStandalonePass(CameraFrameStage::ObjectId), nullptr); + EXPECT_EQ(host.GetCameraFrameStandalonePass(CameraFrameStage::DepthOnly), nullptr); + EXPECT_EQ(host.GetCameraFrameStandalonePass(CameraFrameStage::ShadowCaster), nullptr); +} + TEST(ScriptableRenderPipelineHostAsset_Test, CreatesHostFromRendererAssetAndForwardsDefaults) { auto assetState = std::make_shared(); assetState->defaultFinalColorSettings.outputTransferMode = @@ -4103,6 +4113,9 @@ TEST(ScriptableRenderPipelineHostAsset_Test, CreatesHostFromRendererAssetAndForw ASSERT_NE(host, nullptr); EXPECT_NE(host->GetPipelineRenderer(), nullptr); EXPECT_EQ(assetState->createCalls, 1); + EXPECT_NE(host->GetCameraFrameStandalonePass(CameraFrameStage::ObjectId), nullptr); + EXPECT_NE(host->GetCameraFrameStandalonePass(CameraFrameStage::DepthOnly), nullptr); + EXPECT_NE(host->GetCameraFrameStandalonePass(CameraFrameStage::ShadowCaster), nullptr); } TEST(ManagedScriptableRenderPipelineAsset_Test, CreatesHostWithStageRecorderFromManagedBridge) {