refactor: move scene view post passes into rendering

This commit is contained in:
2026-04-02 04:42:35 +08:00
parent c080890c9d
commit 0d3851204f
6 changed files with 383 additions and 198 deletions

View File

@@ -358,11 +358,13 @@ add_library(XCEngine STATIC
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinObjectIdPass.h
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinInfiniteGridPass.h
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinSceneViewPostPassPlan.h
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinSceneViewPostPassSequenceBuilder.h
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinObjectIdOutlinePass.h
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/CameraRenderer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Passes/BuiltinObjectIdPass.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Passes/BuiltinInfiniteGridPass.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Passes/BuiltinSceneViewPostPassSequenceBuilder.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Passes/BuiltinObjectIdOutlinePass.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/RenderSurface.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/RenderSceneExtractor.cpp

View File

@@ -0,0 +1,59 @@
#pragma once
#include <XCEngine/Rendering/Passes/BuiltinInfiniteGridPass.h>
#include <XCEngine/Rendering/Passes/BuiltinObjectIdOutlinePass.h>
#include <XCEngine/Rendering/RenderPass.h>
#include <cstdint>
#include <vector>
namespace XCEngine {
namespace Rendering {
namespace Passes {
struct BuiltinSceneViewPostPassSequenceInput {
InfiniteGridPassData gridPassData = {};
RHI::RHIResourceView* objectIdTextureView = nullptr;
std::vector<uint64_t> selectedObjectIds = {};
ObjectIdOutlineStyle outlineStyle = {};
};
struct BuiltinSceneViewPostPassSequenceBuildResult {
bool valid = false;
bool missingObjectIdTextureViewForSelection = false;
};
class BuiltinSceneViewPostPassSequenceBuilder {
public:
~BuiltinSceneViewPostPassSequenceBuilder();
void Shutdown();
BuiltinSceneViewPostPassSequenceBuildResult Build(
const BuiltinSceneViewPostPassSequenceInput& input,
RenderPassSequence& outSequence);
private:
void AddColorToRenderTargetPass(RenderPassSequence& outSequence);
void AddInfiniteGridPass(
const InfiniteGridPassData& gridPassData,
RenderPassSequence& outSequence);
void AddSelectionOutlinePass(
RHI::RHIResourceView* objectIdTextureView,
const std::vector<uint64_t>& selectedObjectIds,
const ObjectIdOutlineStyle& outlineStyle,
RenderPassSequence& outSequence);
void AddColorToShaderResourcePass(RenderPassSequence& outSequence);
void AddSelectionMaskDebugPass(
RHI::RHIResourceView* objectIdTextureView,
const std::vector<uint64_t>& selectedObjectIds,
const ObjectIdOutlineStyle& outlineStyle,
RenderPassSequence& outSequence);
BuiltinInfiniteGridPass m_gridPass;
BuiltinObjectIdOutlinePass m_outlinePass;
};
} // namespace Passes
} // namespace Rendering
} // namespace XCEngine

View File

@@ -0,0 +1,214 @@
#include "Rendering/Passes/BuiltinSceneViewPostPassSequenceBuilder.h"
#include "Rendering/Passes/BuiltinSceneViewPostPassPlan.h"
#include <XCEngine/Core/Math/Color.h>
#include <XCEngine/RHI/RHICommandList.h>
#include <functional>
#include <memory>
#include <string>
#include <utility>
namespace XCEngine {
namespace Rendering {
namespace Passes {
namespace {
class LambdaRenderPass final : public RenderPass {
public:
using ExecuteCallback = std::function<bool(const RenderPassContext&)>;
LambdaRenderPass(std::string name, ExecuteCallback executeCallback)
: m_name(std::move(name))
, m_executeCallback(std::move(executeCallback)) {
}
const char* GetName() const override {
return m_name.c_str();
}
bool Execute(const RenderPassContext& context) override {
return m_executeCallback != nullptr && m_executeCallback(context);
}
private:
std::string m_name;
ExecuteCallback m_executeCallback;
};
template <typename Callback>
std::unique_ptr<RenderPass> MakeLambdaRenderPass(const char* name, Callback&& callback) {
return std::make_unique<LambdaRenderPass>(
name,
LambdaRenderPass::ExecuteCallback(std::forward<Callback>(callback)));
}
} // namespace
BuiltinSceneViewPostPassSequenceBuilder::~BuiltinSceneViewPostPassSequenceBuilder() {
Shutdown();
}
void BuiltinSceneViewPostPassSequenceBuilder::Shutdown() {
m_outlinePass.Shutdown();
m_gridPass.Shutdown();
}
BuiltinSceneViewPostPassSequenceBuildResult BuiltinSceneViewPostPassSequenceBuilder::Build(
const BuiltinSceneViewPostPassSequenceInput& input,
RenderPassSequence& outSequence) {
BuiltinSceneViewPostPassSequenceBuildResult result = {};
const bool hasSelection = !input.selectedObjectIds.empty();
const bool hasObjectIdTextureView = input.objectIdTextureView != nullptr;
if (hasSelection && !hasObjectIdTextureView) {
result.missingObjectIdTextureViewForSelection = true;
}
const BuiltinSceneViewPostPassPlan plan = BuildBuiltinSceneViewPostPassPlan({
input.gridPassData.valid,
hasSelection,
input.outlineStyle.debugSelectionMask,
hasObjectIdTextureView
});
if (!plan.valid) {
return result;
}
result.valid = true;
for (const BuiltinSceneViewPostPassStep step : plan.steps) {
switch (step) {
case BuiltinSceneViewPostPassStep::ColorToRenderTarget:
AddColorToRenderTargetPass(outSequence);
break;
case BuiltinSceneViewPostPassStep::InfiniteGrid:
AddInfiniteGridPass(input.gridPassData, outSequence);
break;
case BuiltinSceneViewPostPassStep::SelectionOutline:
AddSelectionOutlinePass(
input.objectIdTextureView,
input.selectedObjectIds,
input.outlineStyle,
outSequence);
break;
case BuiltinSceneViewPostPassStep::ColorToShaderResource:
AddColorToShaderResourcePass(outSequence);
break;
case BuiltinSceneViewPostPassStep::SelectionMaskDebug:
AddSelectionMaskDebugPass(
input.objectIdTextureView,
input.selectedObjectIds,
input.outlineStyle,
outSequence);
break;
default:
break;
}
}
return result;
}
void BuiltinSceneViewPostPassSequenceBuilder::AddColorToRenderTargetPass(
RenderPassSequence& outSequence) {
outSequence.AddPass(MakeLambdaRenderPass(
"SceneColorToRenderTarget",
[](const RenderPassContext& context) {
const std::vector<RHI::RHIResourceView*>& colorAttachments = context.surface.GetColorAttachments();
if (colorAttachments.empty() || colorAttachments[0] == nullptr || context.renderContext.commandList == nullptr) {
return false;
}
context.renderContext.commandList->TransitionBarrier(
colorAttachments[0],
context.surface.GetColorStateAfter(),
RHI::ResourceStates::RenderTarget);
return true;
}));
}
void BuiltinSceneViewPostPassSequenceBuilder::AddInfiniteGridPass(
const InfiniteGridPassData& gridPassData,
RenderPassSequence& outSequence) {
outSequence.AddPass(MakeLambdaRenderPass(
"SceneInfiniteGrid",
[this, gridPassData](const RenderPassContext& context) {
return m_gridPass.Render(
context.renderContext,
context.surface,
gridPassData);
}));
}
void BuiltinSceneViewPostPassSequenceBuilder::AddSelectionOutlinePass(
RHI::RHIResourceView* objectIdTextureView,
const std::vector<uint64_t>& selectedObjectIds,
const ObjectIdOutlineStyle& outlineStyle,
RenderPassSequence& outSequence) {
outSequence.AddPass(MakeLambdaRenderPass(
"SceneSelectionOutline",
[this, objectIdTextureView, selectedObjectIds, outlineStyle](const RenderPassContext& context) {
return m_outlinePass.Render(
context.renderContext,
context.surface,
objectIdTextureView,
selectedObjectIds,
outlineStyle);
}));
}
void BuiltinSceneViewPostPassSequenceBuilder::AddColorToShaderResourcePass(
RenderPassSequence& outSequence) {
outSequence.AddPass(MakeLambdaRenderPass(
"SceneColorToShaderResource",
[](const RenderPassContext& context) {
const std::vector<RHI::RHIResourceView*>& colorAttachments = context.surface.GetColorAttachments();
if (colorAttachments.empty() || colorAttachments[0] == nullptr || context.renderContext.commandList == nullptr) {
return false;
}
context.renderContext.commandList->TransitionBarrier(
colorAttachments[0],
RHI::ResourceStates::RenderTarget,
context.surface.GetColorStateAfter());
return true;
}));
}
void BuiltinSceneViewPostPassSequenceBuilder::AddSelectionMaskDebugPass(
RHI::RHIResourceView* objectIdTextureView,
const std::vector<uint64_t>& selectedObjectIds,
const ObjectIdOutlineStyle& outlineStyle,
RenderPassSequence& outSequence) {
outSequence.AddPass(MakeLambdaRenderPass(
"SceneSelectionMaskDebug",
[this, objectIdTextureView, selectedObjectIds, outlineStyle](const RenderPassContext& context) {
const std::vector<RHI::RHIResourceView*>& colorAttachments = context.surface.GetColorAttachments();
if (colorAttachments.empty() || colorAttachments[0] == nullptr || context.renderContext.commandList == nullptr) {
return false;
}
const float debugClearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
RHI::RHIResourceView* colorView = colorAttachments[0];
context.renderContext.commandList->SetRenderTargets(
1,
&colorView,
context.surface.GetDepthAttachment());
context.renderContext.commandList->ClearRenderTarget(colorView, debugClearColor);
ObjectIdOutlineStyle debugStyle = outlineStyle;
debugStyle.debugSelectionMask = true;
return m_outlinePass.Render(
context.renderContext,
context.surface,
objectIdTextureView,
selectedObjectIds,
debugStyle);
}));
}
} // namespace Passes
} // namespace Rendering
} // namespace XCEngine