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/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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
#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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user