Unify object id rendering with render passes
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/CameraRenderRequest.h>
|
||||
#include <XCEngine/Rendering/ObjectIdPass.h>
|
||||
#include <XCEngine/Rendering/RenderPass.h>
|
||||
#include <XCEngine/Rendering/RenderPipeline.h>
|
||||
|
||||
#include <memory>
|
||||
@@ -25,19 +25,19 @@ public:
|
||||
explicit CameraRenderer(std::shared_ptr<const RenderPipelineAsset> pipelineAsset);
|
||||
CameraRenderer(
|
||||
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> shadowCasterPass = nullptr);
|
||||
~CameraRenderer();
|
||||
|
||||
void SetPipeline(std::unique_ptr<RenderPipeline> pipeline);
|
||||
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 SetShadowCasterPass(std::unique_ptr<RenderPass> 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<const RenderPipelineAsset> m_pipelineAsset;
|
||||
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_shadowCasterPass;
|
||||
std::unique_ptr<DirectionalShadowSurfaceResources> m_directionalShadowSurface;
|
||||
|
||||
@@ -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
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/ObjectIdPass.h>
|
||||
#include <XCEngine/Rendering/ObjectIdEncoding.h>
|
||||
#include <XCEngine/Rendering/RenderPass.h>
|
||||
#include <XCEngine/Rendering/RenderMaterialUtility.h>
|
||||
#include <XCEngine/Rendering/RenderResourceCache.h>
|
||||
#include <XCEngine/Core/Asset/ResourceHandle.h>
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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<RenderPipeline> pipeline)
|
||||
|
||||
CameraRenderer::CameraRenderer(
|
||||
std::unique_ptr<RenderPipeline> pipeline,
|
||||
std::unique_ptr<ObjectIdPass> objectIdPass,
|
||||
std::unique_ptr<RenderPass> objectIdPass,
|
||||
std::unique_ptr<RenderPass> depthOnlyPass,
|
||||
std::unique_ptr<RenderPass> shadowCasterPass)
|
||||
: m_pipelineAsset(nullptr)
|
||||
@@ -254,7 +275,7 @@ void CameraRenderer::SetPipelineAsset(std::shared_ptr<const RenderPipelineAsset>
|
||||
ResetPipeline(CreatePipelineFromAsset(m_pipelineAsset));
|
||||
}
|
||||
|
||||
void CameraRenderer::SetObjectIdPass(std::unique_ptr<ObjectIdPass> objectIdPass) {
|
||||
void CameraRenderer::SetObjectIdPass(std::unique_ptr<RenderPass> 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;
|
||||
}
|
||||
|
||||
@@ -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<RHI::RHIResourceView*>& colorAttachments = surface.GetColorAttachments();
|
||||
if (colorAttachments.empty() || colorAttachments[0] == nullptr || surface.GetDepthAttachment() == nullptr) {
|
||||
const std::vector<RHI::RHIResourceView*>& 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<float>(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;
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <XCEngine/RHI/RHITexture.h>
|
||||
#include <XCEngine/Core/Math/Vector4.h>
|
||||
#include <XCEngine/Rendering/CameraRenderer.h>
|
||||
#include <XCEngine/Rendering/ObjectIdPass.h>
|
||||
#include <XCEngine/Rendering/RenderPipelineAsset.h>
|
||||
#include <XCEngine/Rendering/RenderSurface.h>
|
||||
#include <XCEngine/Rendering/SceneRenderer.h>
|
||||
@@ -326,7 +325,7 @@ private:
|
||||
std::shared_ptr<MockPipelineAssetState> m_state;
|
||||
};
|
||||
|
||||
class MockObjectIdPass final : public ObjectIdPass {
|
||||
class MockObjectIdPass final : public RenderPass {
|
||||
public:
|
||||
MockObjectIdPass(
|
||||
std::shared_ptr<MockPipelineState> 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user