refactor: extract scene viewport post-pass planning

This commit is contained in:
2026-03-31 21:54:00 +08:00
parent ad237cb81e
commit f85fa78dd1
6 changed files with 435 additions and 114 deletions

View File

@@ -7,6 +7,7 @@
#include "SceneViewportPicker.h"
#include "SceneViewportCameraController.h"
#include "SceneViewportInfiniteGridPass.h"
#include "SceneViewportPostPassPlan.h"
#include "SceneViewportSelectionMaskPass.h"
#include "SceneViewportSelectionOutlinePass.h"
#include "SceneViewportSelectionUtils.h"
@@ -534,59 +535,35 @@ private:
const Rendering::RenderCameraData& cameraData,
const std::vector<Rendering::VisibleRenderItem>& selectionRenderables,
Rendering::RenderPassSequence& outPostPasses) {
if (!overlay.valid) {
const bool hasSelection = !selectionRenderables.empty();
const bool hasSelectionMaskRenderTarget = entry.selectionMaskView != nullptr;
const bool hasSelectionMaskShaderView = entry.selectionMaskShaderView != nullptr;
if (hasSelection &&
!kDebugSceneSelectionMask &&
(!hasSelectionMaskRenderTarget || !hasSelectionMaskShaderView)) {
SetViewportStatusIfEmpty(entry.statusText, "Scene selection mask target is unavailable");
}
const SceneViewportPostPassPlan plan = BuildSceneViewportPostPassPlan({
overlay.valid,
hasSelection,
kDebugSceneSelectionMask,
hasSelectionMaskRenderTarget,
hasSelectionMaskShaderView
});
if (!plan.valid) {
return false;
}
const bool hasSelection = !selectionRenderables.empty();
if (hasSelection && kDebugSceneSelectionMask) {
outPostPasses.AddPass(MakeLambdaRenderPass(
"SceneColorToRenderTarget",
[&entry](const Rendering::RenderPassContext& context) {
context.renderContext.commandList->TransitionBarrier(
entry.colorView,
context.surface.GetColorStateAfter(),
RHI::ResourceStates::RenderTarget);
entry.colorState = RHI::ResourceStates::RenderTarget;
return true;
}));
outPostPasses.AddPass(MakeLambdaRenderPass(
"SceneSelectionMaskDebug",
[this, &entry, &cameraData, &selectionRenderables](
const Rendering::RenderPassContext& context) {
const float debugClearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
RHI::RHIResourceView* colorView = entry.colorView;
context.renderContext.commandList->SetRenderTargets(1, &colorView, entry.depthView);
context.renderContext.commandList->ClearRenderTarget(colorView, debugClearColor);
const bool rendered = m_sceneSelectionMaskPass.Render(
context.renderContext,
context.surface,
cameraData,
selectionRenderables);
if (!rendered) {
SetViewportStatusIfEmpty(entry.statusText, "Scene selection mask debug pass failed");
}
return rendered;
}));
outPostPasses.AddPass(MakeLambdaRenderPass(
"SceneColorToShaderResource",
[&entry](const Rendering::RenderPassContext& context) {
context.renderContext.commandList->TransitionBarrier(
entry.colorView,
RHI::ResourceStates::RenderTarget,
context.surface.GetColorStateAfter());
entry.colorState = context.surface.GetColorStateAfter();
return true;
}));
return true;
Rendering::RenderSurface selectionMaskSurface = {};
if (plan.usesSelectionMaskSurface) {
selectionMaskSurface = BuildSelectionMaskSurface(entry);
}
if (hasSelection) {
if (entry.selectionMaskView == nullptr || entry.selectionMaskShaderView == nullptr) {
SetViewportStatusIfEmpty(entry.statusText, "Scene selection mask target is unavailable");
} else {
Rendering::RenderSurface selectionMaskSurface = BuildSelectionMaskSurface(entry);
for (const SceneViewportPostPassStep step : plan.steps) {
switch (step) {
case SceneViewportPostPassStep::SelectionMask:
outPostPasses.AddPass(MakeLambdaRenderPass(
"SceneSelectionMask",
[this, &entry, selectionMaskSurface, &cameraData, &selectionRenderables](
@@ -618,57 +595,85 @@ private:
entry.selectionMaskState = RHI::ResourceStates::PixelShaderResource;
return rendered;
}));
break;
case SceneViewportPostPassStep::ColorToRenderTarget:
outPostPasses.AddPass(MakeLambdaRenderPass(
"SceneColorToRenderTarget",
[&entry](const Rendering::RenderPassContext& context) {
context.renderContext.commandList->TransitionBarrier(
entry.colorView,
context.surface.GetColorStateAfter(),
RHI::ResourceStates::RenderTarget);
entry.colorState = RHI::ResourceStates::RenderTarget;
return true;
}));
break;
case SceneViewportPostPassStep::InfiniteGrid:
outPostPasses.AddPass(MakeLambdaRenderPass(
"SceneInfiniteGrid",
[this, overlay, &entry](const Rendering::RenderPassContext& context) {
const bool rendered = m_sceneGridPass.Render(
context.renderContext,
context.surface,
overlay);
if (!rendered) {
SetViewportStatusIfEmpty(entry.statusText, "Scene grid pass failed");
}
return rendered;
}));
break;
case SceneViewportPostPassStep::SelectionOutline:
outPostPasses.AddPass(MakeLambdaRenderPass(
"SceneSelectionOutline",
[this, &entry](const Rendering::RenderPassContext& context) {
const bool rendered = m_sceneSelectionOutlinePass.Render(
context.renderContext,
context.surface,
entry.selectionMaskShaderView);
if (!rendered) {
SetViewportStatusIfEmpty(entry.statusText, "Scene selection outline pass failed");
}
return rendered;
}));
break;
case SceneViewportPostPassStep::ColorToShaderResource:
outPostPasses.AddPass(MakeLambdaRenderPass(
"SceneColorToShaderResource",
[&entry](const Rendering::RenderPassContext& context) {
context.renderContext.commandList->TransitionBarrier(
entry.colorView,
RHI::ResourceStates::RenderTarget,
context.surface.GetColorStateAfter());
entry.colorState = context.surface.GetColorStateAfter();
return true;
}));
break;
case SceneViewportPostPassStep::SelectionMaskDebug:
outPostPasses.AddPass(MakeLambdaRenderPass(
"SceneSelectionMaskDebug",
[this, &entry, &cameraData, &selectionRenderables](
const Rendering::RenderPassContext& context) {
const float debugClearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
RHI::RHIResourceView* colorView = entry.colorView;
context.renderContext.commandList->SetRenderTargets(1, &colorView, entry.depthView);
context.renderContext.commandList->ClearRenderTarget(colorView, debugClearColor);
const bool rendered = m_sceneSelectionMaskPass.Render(
context.renderContext,
context.surface,
cameraData,
selectionRenderables);
if (!rendered) {
SetViewportStatusIfEmpty(entry.statusText, "Scene selection mask debug pass failed");
}
return rendered;
}));
break;
default:
break;
}
}
outPostPasses.AddPass(MakeLambdaRenderPass(
"SceneColorToRenderTarget",
[&entry](const Rendering::RenderPassContext& context) {
context.renderContext.commandList->TransitionBarrier(
entry.colorView,
context.surface.GetColorStateAfter(),
RHI::ResourceStates::RenderTarget);
entry.colorState = RHI::ResourceStates::RenderTarget;
return true;
}));
outPostPasses.AddPass(MakeLambdaRenderPass(
"SceneInfiniteGrid",
[this, overlay, &entry](const Rendering::RenderPassContext& context) {
const bool rendered = m_sceneGridPass.Render(
context.renderContext,
context.surface,
overlay);
if (!rendered) {
SetViewportStatusIfEmpty(entry.statusText, "Scene grid pass failed");
}
return rendered;
}));
if (hasSelection && entry.selectionMaskShaderView != nullptr) {
outPostPasses.AddPass(MakeLambdaRenderPass(
"SceneSelectionOutline",
[this, &entry](const Rendering::RenderPassContext& context) {
const bool rendered = m_sceneSelectionOutlinePass.Render(
context.renderContext,
context.surface,
entry.selectionMaskShaderView);
if (!rendered) {
SetViewportStatusIfEmpty(entry.statusText, "Scene selection outline pass failed");
}
return rendered;
}));
}
outPostPasses.AddPass(MakeLambdaRenderPass(
"SceneColorToShaderResource",
[&entry](const Rendering::RenderPassContext& context) {
context.renderContext.commandList->TransitionBarrier(
entry.colorView,
RHI::ResourceStates::RenderTarget,
context.surface.GetColorStateAfter());
entry.colorState = context.surface.GetColorStateAfter();
return true;
}));
return true;
}