From 8ced88e8476dcc41dafb80a371dc93fe649d99c9 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Sun, 5 Apr 2026 18:20:19 +0800 Subject: [PATCH] Unify object id rendering with render passes --- engine/CMakeLists.txt | 1 - .../XCEngine/Rendering/CameraRenderer.h | 10 ++--- .../include/XCEngine/Rendering/ObjectIdPass.h | 24 ---------- .../Rendering/Passes/BuiltinObjectIdPass.h | 12 ++--- engine/src/Rendering/CameraRenderer.cpp | 32 +++++++++++-- .../Rendering/Passes/BuiltinObjectIdPass.cpp | 45 +++++++++++-------- .../unit/test_camera_scene_renderer.cpp | 12 ++--- 7 files changed, 72 insertions(+), 64 deletions(-) delete mode 100644 engine/include/XCEngine/Rendering/ObjectIdPass.h diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 9263e805..9d9ad09b 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -440,7 +440,6 @@ add_library(XCEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/RenderResourceCache.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/CameraRenderer.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/ObjectIdEncoding.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/ObjectIdPass.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/SceneRenderRequestPlanner.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/SceneRenderRequestUtils.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/SceneRenderer.h diff --git a/engine/include/XCEngine/Rendering/CameraRenderer.h b/engine/include/XCEngine/Rendering/CameraRenderer.h index fa70624e..1024664b 100644 --- a/engine/include/XCEngine/Rendering/CameraRenderer.h +++ b/engine/include/XCEngine/Rendering/CameraRenderer.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include @@ -25,19 +25,19 @@ public: explicit CameraRenderer(std::shared_ptr pipelineAsset); CameraRenderer( std::unique_ptr pipeline, - std::unique_ptr objectIdPass, + std::unique_ptr objectIdPass, std::unique_ptr depthOnlyPass = nullptr, std::unique_ptr shadowCasterPass = nullptr); ~CameraRenderer(); void SetPipeline(std::unique_ptr pipeline); void SetPipelineAsset(std::shared_ptr pipelineAsset); - void SetObjectIdPass(std::unique_ptr objectIdPass); + void SetObjectIdPass(std::unique_ptr objectIdPass); void SetDepthOnlyPass(std::unique_ptr depthOnlyPass); void SetShadowCasterPass(std::unique_ptr shadowCasterPass); RenderPipeline* GetPipeline() const { return m_pipeline.get(); } const RenderPipelineAsset* GetPipelineAsset() const { return m_pipelineAsset.get(); } - ObjectIdPass* GetObjectIdPass() const { return m_objectIdPass.get(); } + RenderPass* GetObjectIdPass() const { return m_objectIdPass.get(); } RenderPass* GetDepthOnlyPass() const { return m_depthOnlyPass.get(); } RenderPass* GetShadowCasterPass() const { return m_shadowCasterPass.get(); } @@ -54,7 +54,7 @@ private: RenderSceneExtractor m_sceneExtractor; std::shared_ptr m_pipelineAsset; std::unique_ptr m_pipeline; - std::unique_ptr m_objectIdPass; + std::unique_ptr m_objectIdPass; std::unique_ptr m_depthOnlyPass; std::unique_ptr m_shadowCasterPass; std::unique_ptr m_directionalShadowSurface; diff --git a/engine/include/XCEngine/Rendering/ObjectIdPass.h b/engine/include/XCEngine/Rendering/ObjectIdPass.h deleted file mode 100644 index 27e10ee7..00000000 --- a/engine/include/XCEngine/Rendering/ObjectIdPass.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace XCEngine { -namespace Rendering { - -class ObjectIdPass { -public: - virtual ~ObjectIdPass() = default; - - virtual bool Render( - const RenderContext& context, - const RenderSurface& surface, - const RenderSceneData& sceneData) = 0; - - virtual void Shutdown() { - } -}; - -} // namespace Rendering -} // namespace XCEngine diff --git a/engine/include/XCEngine/Rendering/Passes/BuiltinObjectIdPass.h b/engine/include/XCEngine/Rendering/Passes/BuiltinObjectIdPass.h index 462fbc3f..5d817eec 100644 --- a/engine/include/XCEngine/Rendering/Passes/BuiltinObjectIdPass.h +++ b/engine/include/XCEngine/Rendering/Passes/BuiltinObjectIdPass.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include #include #include #include @@ -14,16 +14,16 @@ namespace XCEngine { namespace Rendering { namespace Passes { -class BuiltinObjectIdPass final : public ObjectIdPass { +class BuiltinObjectIdPass final : public RenderPass { public: ~BuiltinObjectIdPass() override; static RHI::InputLayoutDesc BuildInputLayout(); - bool Render( - const RenderContext& context, - const RenderSurface& surface, - const RenderSceneData& sceneData) override; + const char* GetName() const override; + + bool Initialize(const RenderContext& context) override; + bool Execute(const RenderPassContext& context) override; void Shutdown() override; diff --git a/engine/src/Rendering/CameraRenderer.cpp b/engine/src/Rendering/CameraRenderer.cpp index 39125061..58c07cbe 100644 --- a/engine/src/Rendering/CameraRenderer.cpp +++ b/engine/src/Rendering/CameraRenderer.cpp @@ -167,6 +167,27 @@ bool ExecuteScenePassRequest( return pass->Execute(passContext); } +bool ExecuteStandalonePass( + RenderPass* pass, + const RenderContext& context, + const RenderSurface& surface, + const RenderSceneData& sceneData) { + if (pass == nullptr) { + return false; + } + + if (!InitializeStandalonePass(pass, context)) { + return false; + } + + const RenderPassContext passContext = { + context, + surface, + sceneData + }; + return pass->Execute(passContext); +} + RenderDirectionalShadowData BuildDirectionalShadowData( const DirectionalShadowRenderPlan& plan, RHI::RHIResourceView* shadowMapView) { @@ -202,7 +223,7 @@ CameraRenderer::CameraRenderer(std::unique_ptr pipeline) CameraRenderer::CameraRenderer( std::unique_ptr pipeline, - std::unique_ptr objectIdPass, + std::unique_ptr objectIdPass, std::unique_ptr depthOnlyPass, std::unique_ptr shadowCasterPass) : m_pipelineAsset(nullptr) @@ -254,7 +275,7 @@ void CameraRenderer::SetPipelineAsset(std::shared_ptr ResetPipeline(CreatePipelineFromAsset(m_pipelineAsset)); } -void CameraRenderer::SetObjectIdPass(std::unique_ptr objectIdPass) { +void CameraRenderer::SetObjectIdPass(std::unique_ptr objectIdPass) { if (m_objectIdPass != nullptr) { m_objectIdPass->Shutdown(); } @@ -471,8 +492,11 @@ bool CameraRenderer::Render( } if (request.objectId.IsRequested() && - (m_objectIdPass == nullptr || - !m_objectIdPass->Render(request.context, request.objectId.surface, sceneData))) { + !ExecuteStandalonePass( + m_objectIdPass.get(), + request.context, + request.objectId.surface, + sceneData)) { ShutdownPassSequence(request.preScenePasses, preScenePassesInitialized); return false; } diff --git a/engine/src/Rendering/Passes/BuiltinObjectIdPass.cpp b/engine/src/Rendering/Passes/BuiltinObjectIdPass.cpp index d0291fc7..5f60257a 100644 --- a/engine/src/Rendering/Passes/BuiltinObjectIdPass.cpp +++ b/engine/src/Rendering/Passes/BuiltinObjectIdPass.cpp @@ -8,6 +8,8 @@ #include "RHI/RHIPipelineState.h" #include "Rendering/Detail/ShaderVariantUtils.h" #include "Rendering/RenderMaterialUtility.h" +#include "Rendering/RenderSceneExtractor.h" +#include "Rendering/RenderSurface.h" #include "Resources/BuiltinResources.h" #include "Resources/Mesh/Mesh.h" @@ -95,6 +97,10 @@ BuiltinObjectIdPass::~BuiltinObjectIdPass() { Shutdown(); } +const char* BuiltinObjectIdPass::GetName() const { + return "BuiltinObjectIdPass"; +} + RHI::InputLayoutDesc BuiltinObjectIdPass::BuildInputLayout() { RHI::InputLayoutDesc inputLayout = {}; @@ -125,39 +131,42 @@ RHI::InputLayoutDesc BuiltinObjectIdPass::BuildInputLayout() { return inputLayout; } -bool BuiltinObjectIdPass::Render( - const RenderContext& context, - const RenderSurface& surface, - const RenderSceneData& sceneData) { - if (!context.IsValid()) { +bool BuiltinObjectIdPass::Initialize(const RenderContext& context) { + return EnsureInitialized(context); +} + +bool BuiltinObjectIdPass::Execute(const RenderPassContext& context) { + if (!context.renderContext.IsValid()) { return false; } - const std::vector& colorAttachments = surface.GetColorAttachments(); - if (colorAttachments.empty() || colorAttachments[0] == nullptr || surface.GetDepthAttachment() == nullptr) { + const std::vector& colorAttachments = context.surface.GetColorAttachments(); + if (colorAttachments.empty() || + colorAttachments[0] == nullptr || + context.surface.GetDepthAttachment() == nullptr) { return false; } - const Math::RectInt renderArea = surface.GetRenderArea(); + const Math::RectInt renderArea = context.surface.GetRenderArea(); if (renderArea.width <= 0 || renderArea.height <= 0) { return false; } - if (!EnsureInitialized(context)) { + if (!EnsureInitialized(context.renderContext)) { return false; } - RHI::RHICommandList* commandList = context.commandList; + RHI::RHICommandList* commandList = context.renderContext.commandList; RHI::RHIResourceView* renderTarget = colorAttachments[0]; - if (surface.IsAutoTransitionEnabled()) { + if (context.surface.IsAutoTransitionEnabled()) { commandList->TransitionBarrier( renderTarget, - surface.GetColorStateBefore(), + context.surface.GetColorStateBefore(), RHI::ResourceStates::RenderTarget); } - commandList->SetRenderTargets(1, &renderTarget, surface.GetDepthAttachment()); + commandList->SetRenderTargets(1, &renderTarget, context.surface.GetDepthAttachment()); const RHI::Viewport viewport = { static_cast(renderArea.x), @@ -179,21 +188,21 @@ bool BuiltinObjectIdPass::Render( commandList->SetViewport(viewport); commandList->SetScissorRect(scissorRect); commandList->ClearRenderTarget(renderTarget, clearColor, 1, clearRects); - commandList->ClearDepthStencil(surface.GetDepthAttachment(), 1.0f, 0, 1, clearRects); + commandList->ClearDepthStencil(context.surface.GetDepthAttachment(), 1.0f, 0, 1, clearRects); commandList->SetPrimitiveTopology(RHI::PrimitiveTopology::TriangleList); commandList->SetPipelineState(m_pipelineState); - for (const VisibleRenderItem& visibleItem : sceneData.visibleItems) { - DrawVisibleItem(context, sceneData, visibleItem); + for (const VisibleRenderItem& visibleItem : context.sceneData.visibleItems) { + DrawVisibleItem(context.renderContext, context.sceneData, visibleItem); } commandList->EndRenderPass(); - if (surface.IsAutoTransitionEnabled()) { + if (context.surface.IsAutoTransitionEnabled()) { commandList->TransitionBarrier( renderTarget, RHI::ResourceStates::RenderTarget, - surface.GetColorStateAfter()); + context.surface.GetColorStateAfter()); } return true; diff --git a/tests/Rendering/unit/test_camera_scene_renderer.cpp b/tests/Rendering/unit/test_camera_scene_renderer.cpp index 75ff366d..aacb22f7 100644 --- a/tests/Rendering/unit/test_camera_scene_renderer.cpp +++ b/tests/Rendering/unit/test_camera_scene_renderer.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -326,7 +325,7 @@ private: std::shared_ptr m_state; }; -class MockObjectIdPass final : public ObjectIdPass { +class MockObjectIdPass final : public RenderPass { public: MockObjectIdPass( std::shared_ptr state, @@ -335,10 +334,11 @@ public: , m_renderResult(renderResult) { } - bool Render( - const RenderContext&, - const RenderSurface&, - const RenderSceneData&) override { + const char* GetName() const override { + return "MockObjectIdPass"; + } + + bool Execute(const RenderPassContext&) override { m_state->eventLog.push_back("objectId"); return m_renderResult; }