Unify object id rendering with render passes

This commit is contained in:
2026-04-05 18:20:19 +08:00
parent a600e73fb2
commit 8ced88e847
7 changed files with 72 additions and 64 deletions

View File

@@ -440,7 +440,6 @@ add_library(XCEngine STATIC
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/RenderResourceCache.h ${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/CameraRenderer.h
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/ObjectIdEncoding.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/SceneRenderRequestPlanner.h
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/SceneRenderRequestUtils.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/SceneRenderRequestUtils.h
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/SceneRenderer.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/SceneRenderer.h

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <XCEngine/Rendering/CameraRenderRequest.h> #include <XCEngine/Rendering/CameraRenderRequest.h>
#include <XCEngine/Rendering/ObjectIdPass.h> #include <XCEngine/Rendering/RenderPass.h>
#include <XCEngine/Rendering/RenderPipeline.h> #include <XCEngine/Rendering/RenderPipeline.h>
#include <memory> #include <memory>
@@ -25,19 +25,19 @@ public:
explicit CameraRenderer(std::shared_ptr<const RenderPipelineAsset> pipelineAsset); explicit CameraRenderer(std::shared_ptr<const RenderPipelineAsset> pipelineAsset);
CameraRenderer( CameraRenderer(
std::unique_ptr<RenderPipeline> pipeline, std::unique_ptr<RenderPipeline> pipeline,
std::unique_ptr<ObjectIdPass> objectIdPass, std::unique_ptr<RenderPass> objectIdPass,
std::unique_ptr<RenderPass> depthOnlyPass = nullptr, std::unique_ptr<RenderPass> depthOnlyPass = nullptr,
std::unique_ptr<RenderPass> shadowCasterPass = nullptr); std::unique_ptr<RenderPass> shadowCasterPass = nullptr);
~CameraRenderer(); ~CameraRenderer();
void SetPipeline(std::unique_ptr<RenderPipeline> pipeline); void SetPipeline(std::unique_ptr<RenderPipeline> pipeline);
void SetPipelineAsset(std::shared_ptr<const RenderPipelineAsset> pipelineAsset); void SetPipelineAsset(std::shared_ptr<const RenderPipelineAsset> pipelineAsset);
void SetObjectIdPass(std::unique_ptr<ObjectIdPass> objectIdPass); void SetObjectIdPass(std::unique_ptr<RenderPass> objectIdPass);
void SetDepthOnlyPass(std::unique_ptr<RenderPass> depthOnlyPass); void SetDepthOnlyPass(std::unique_ptr<RenderPass> depthOnlyPass);
void SetShadowCasterPass(std::unique_ptr<RenderPass> shadowCasterPass); void SetShadowCasterPass(std::unique_ptr<RenderPass> shadowCasterPass);
RenderPipeline* GetPipeline() const { return m_pipeline.get(); } RenderPipeline* GetPipeline() const { return m_pipeline.get(); }
const RenderPipelineAsset* GetPipelineAsset() const { return m_pipelineAsset.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* GetDepthOnlyPass() const { return m_depthOnlyPass.get(); }
RenderPass* GetShadowCasterPass() const { return m_shadowCasterPass.get(); } RenderPass* GetShadowCasterPass() const { return m_shadowCasterPass.get(); }
@@ -54,7 +54,7 @@ private:
RenderSceneExtractor m_sceneExtractor; RenderSceneExtractor m_sceneExtractor;
std::shared_ptr<const RenderPipelineAsset> m_pipelineAsset; std::shared_ptr<const RenderPipelineAsset> m_pipelineAsset;
std::unique_ptr<RenderPipeline> m_pipeline; std::unique_ptr<RenderPipeline> m_pipeline;
std::unique_ptr<ObjectIdPass> m_objectIdPass; std::unique_ptr<RenderPass> m_objectIdPass;
std::unique_ptr<RenderPass> m_depthOnlyPass; std::unique_ptr<RenderPass> m_depthOnlyPass;
std::unique_ptr<RenderPass> m_shadowCasterPass; std::unique_ptr<RenderPass> m_shadowCasterPass;
std::unique_ptr<DirectionalShadowSurfaceResources> m_directionalShadowSurface; std::unique_ptr<DirectionalShadowSurfaceResources> m_directionalShadowSurface;

View File

@@ -1,24 +0,0 @@
#pragma once
#include <XCEngine/Rendering/RenderContext.h>
#include <XCEngine/Rendering/RenderSceneExtractor.h>
#include <XCEngine/Rendering/RenderSurface.h>
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

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <XCEngine/Rendering/ObjectIdPass.h>
#include <XCEngine/Rendering/ObjectIdEncoding.h> #include <XCEngine/Rendering/ObjectIdEncoding.h>
#include <XCEngine/Rendering/RenderPass.h>
#include <XCEngine/Rendering/RenderMaterialUtility.h> #include <XCEngine/Rendering/RenderMaterialUtility.h>
#include <XCEngine/Rendering/RenderResourceCache.h> #include <XCEngine/Rendering/RenderResourceCache.h>
#include <XCEngine/Core/Asset/ResourceHandle.h> #include <XCEngine/Core/Asset/ResourceHandle.h>
@@ -14,16 +14,16 @@ namespace XCEngine {
namespace Rendering { namespace Rendering {
namespace Passes { namespace Passes {
class BuiltinObjectIdPass final : public ObjectIdPass { class BuiltinObjectIdPass final : public RenderPass {
public: public:
~BuiltinObjectIdPass() override; ~BuiltinObjectIdPass() override;
static RHI::InputLayoutDesc BuildInputLayout(); static RHI::InputLayoutDesc BuildInputLayout();
bool Render( const char* GetName() const override;
const RenderContext& context,
const RenderSurface& surface, bool Initialize(const RenderContext& context) override;
const RenderSceneData& sceneData) override; bool Execute(const RenderPassContext& context) override;
void Shutdown() override; void Shutdown() override;

View File

@@ -167,6 +167,27 @@ bool ExecuteScenePassRequest(
return pass->Execute(passContext); 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( RenderDirectionalShadowData BuildDirectionalShadowData(
const DirectionalShadowRenderPlan& plan, const DirectionalShadowRenderPlan& plan,
RHI::RHIResourceView* shadowMapView) { RHI::RHIResourceView* shadowMapView) {
@@ -202,7 +223,7 @@ CameraRenderer::CameraRenderer(std::unique_ptr<RenderPipeline> pipeline)
CameraRenderer::CameraRenderer( CameraRenderer::CameraRenderer(
std::unique_ptr<RenderPipeline> pipeline, std::unique_ptr<RenderPipeline> pipeline,
std::unique_ptr<ObjectIdPass> objectIdPass, std::unique_ptr<RenderPass> objectIdPass,
std::unique_ptr<RenderPass> depthOnlyPass, std::unique_ptr<RenderPass> depthOnlyPass,
std::unique_ptr<RenderPass> shadowCasterPass) std::unique_ptr<RenderPass> shadowCasterPass)
: m_pipelineAsset(nullptr) : m_pipelineAsset(nullptr)
@@ -254,7 +275,7 @@ void CameraRenderer::SetPipelineAsset(std::shared_ptr<const RenderPipelineAsset>
ResetPipeline(CreatePipelineFromAsset(m_pipelineAsset)); ResetPipeline(CreatePipelineFromAsset(m_pipelineAsset));
} }
void CameraRenderer::SetObjectIdPass(std::unique_ptr<ObjectIdPass> objectIdPass) { void CameraRenderer::SetObjectIdPass(std::unique_ptr<RenderPass> objectIdPass) {
if (m_objectIdPass != nullptr) { if (m_objectIdPass != nullptr) {
m_objectIdPass->Shutdown(); m_objectIdPass->Shutdown();
} }
@@ -471,8 +492,11 @@ bool CameraRenderer::Render(
} }
if (request.objectId.IsRequested() && if (request.objectId.IsRequested() &&
(m_objectIdPass == nullptr || !ExecuteStandalonePass(
!m_objectIdPass->Render(request.context, request.objectId.surface, sceneData))) { m_objectIdPass.get(),
request.context,
request.objectId.surface,
sceneData)) {
ShutdownPassSequence(request.preScenePasses, preScenePassesInitialized); ShutdownPassSequence(request.preScenePasses, preScenePassesInitialized);
return false; return false;
} }

View File

@@ -8,6 +8,8 @@
#include "RHI/RHIPipelineState.h" #include "RHI/RHIPipelineState.h"
#include "Rendering/Detail/ShaderVariantUtils.h" #include "Rendering/Detail/ShaderVariantUtils.h"
#include "Rendering/RenderMaterialUtility.h" #include "Rendering/RenderMaterialUtility.h"
#include "Rendering/RenderSceneExtractor.h"
#include "Rendering/RenderSurface.h"
#include "Resources/BuiltinResources.h" #include "Resources/BuiltinResources.h"
#include "Resources/Mesh/Mesh.h" #include "Resources/Mesh/Mesh.h"
@@ -95,6 +97,10 @@ BuiltinObjectIdPass::~BuiltinObjectIdPass() {
Shutdown(); Shutdown();
} }
const char* BuiltinObjectIdPass::GetName() const {
return "BuiltinObjectIdPass";
}
RHI::InputLayoutDesc BuiltinObjectIdPass::BuildInputLayout() { RHI::InputLayoutDesc BuiltinObjectIdPass::BuildInputLayout() {
RHI::InputLayoutDesc inputLayout = {}; RHI::InputLayoutDesc inputLayout = {};
@@ -125,39 +131,42 @@ RHI::InputLayoutDesc BuiltinObjectIdPass::BuildInputLayout() {
return inputLayout; return inputLayout;
} }
bool BuiltinObjectIdPass::Render( bool BuiltinObjectIdPass::Initialize(const RenderContext& context) {
const RenderContext& context, return EnsureInitialized(context);
const RenderSurface& surface, }
const RenderSceneData& sceneData) {
if (!context.IsValid()) { bool BuiltinObjectIdPass::Execute(const RenderPassContext& context) {
if (!context.renderContext.IsValid()) {
return false; return false;
} }
const std::vector<RHI::RHIResourceView*>& colorAttachments = surface.GetColorAttachments(); const std::vector<RHI::RHIResourceView*>& colorAttachments = context.surface.GetColorAttachments();
if (colorAttachments.empty() || colorAttachments[0] == nullptr || surface.GetDepthAttachment() == nullptr) { if (colorAttachments.empty() ||
colorAttachments[0] == nullptr ||
context.surface.GetDepthAttachment() == nullptr) {
return false; return false;
} }
const Math::RectInt renderArea = surface.GetRenderArea(); const Math::RectInt renderArea = context.surface.GetRenderArea();
if (renderArea.width <= 0 || renderArea.height <= 0) { if (renderArea.width <= 0 || renderArea.height <= 0) {
return false; return false;
} }
if (!EnsureInitialized(context)) { if (!EnsureInitialized(context.renderContext)) {
return false; return false;
} }
RHI::RHICommandList* commandList = context.commandList; RHI::RHICommandList* commandList = context.renderContext.commandList;
RHI::RHIResourceView* renderTarget = colorAttachments[0]; RHI::RHIResourceView* renderTarget = colorAttachments[0];
if (surface.IsAutoTransitionEnabled()) { if (context.surface.IsAutoTransitionEnabled()) {
commandList->TransitionBarrier( commandList->TransitionBarrier(
renderTarget, renderTarget,
surface.GetColorStateBefore(), context.surface.GetColorStateBefore(),
RHI::ResourceStates::RenderTarget); RHI::ResourceStates::RenderTarget);
} }
commandList->SetRenderTargets(1, &renderTarget, surface.GetDepthAttachment()); commandList->SetRenderTargets(1, &renderTarget, context.surface.GetDepthAttachment());
const RHI::Viewport viewport = { const RHI::Viewport viewport = {
static_cast<float>(renderArea.x), static_cast<float>(renderArea.x),
@@ -179,21 +188,21 @@ bool BuiltinObjectIdPass::Render(
commandList->SetViewport(viewport); commandList->SetViewport(viewport);
commandList->SetScissorRect(scissorRect); commandList->SetScissorRect(scissorRect);
commandList->ClearRenderTarget(renderTarget, clearColor, 1, clearRects); 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->SetPrimitiveTopology(RHI::PrimitiveTopology::TriangleList);
commandList->SetPipelineState(m_pipelineState); commandList->SetPipelineState(m_pipelineState);
for (const VisibleRenderItem& visibleItem : sceneData.visibleItems) { for (const VisibleRenderItem& visibleItem : context.sceneData.visibleItems) {
DrawVisibleItem(context, sceneData, visibleItem); DrawVisibleItem(context.renderContext, context.sceneData, visibleItem);
} }
commandList->EndRenderPass(); commandList->EndRenderPass();
if (surface.IsAutoTransitionEnabled()) { if (context.surface.IsAutoTransitionEnabled()) {
commandList->TransitionBarrier( commandList->TransitionBarrier(
renderTarget, renderTarget,
RHI::ResourceStates::RenderTarget, RHI::ResourceStates::RenderTarget,
surface.GetColorStateAfter()); context.surface.GetColorStateAfter());
} }
return true; return true;

View File

@@ -8,7 +8,6 @@
#include <XCEngine/RHI/RHITexture.h> #include <XCEngine/RHI/RHITexture.h>
#include <XCEngine/Core/Math/Vector4.h> #include <XCEngine/Core/Math/Vector4.h>
#include <XCEngine/Rendering/CameraRenderer.h> #include <XCEngine/Rendering/CameraRenderer.h>
#include <XCEngine/Rendering/ObjectIdPass.h>
#include <XCEngine/Rendering/RenderPipelineAsset.h> #include <XCEngine/Rendering/RenderPipelineAsset.h>
#include <XCEngine/Rendering/RenderSurface.h> #include <XCEngine/Rendering/RenderSurface.h>
#include <XCEngine/Rendering/SceneRenderer.h> #include <XCEngine/Rendering/SceneRenderer.h>
@@ -326,7 +325,7 @@ private:
std::shared_ptr<MockPipelineAssetState> m_state; std::shared_ptr<MockPipelineAssetState> m_state;
}; };
class MockObjectIdPass final : public ObjectIdPass { class MockObjectIdPass final : public RenderPass {
public: public:
MockObjectIdPass( MockObjectIdPass(
std::shared_ptr<MockPipelineState> state, std::shared_ptr<MockPipelineState> state,
@@ -335,10 +334,11 @@ public:
, m_renderResult(renderResult) { , m_renderResult(renderResult) {
} }
bool Render( const char* GetName() const override {
const RenderContext&, return "MockObjectIdPass";
const RenderSurface&, }
const RenderSceneData&) override {
bool Execute(const RenderPassContext&) override {
m_state->eventLog.push_back("objectId"); m_state->eventLog.push_back("objectId");
return m_renderResult; return m_renderResult;
} }