Lower final color into final output stage

This commit is contained in:
2026-04-06 16:15:19 +08:00
parent 6645d507d0
commit 33bb84f650
17 changed files with 1149 additions and 42 deletions

View File

@@ -3,12 +3,40 @@
#include "Components/CameraComponent.h"
#include "Rendering/Caches/FullscreenPassSurfaceCache.h"
#include "Rendering/Planning/CameraPostProcessPassFactory.h"
#include "Rendering/Planning/FinalColorPassFactory.h"
#include "Rendering/Planning/SceneRenderRequestUtils.h"
#include "Rendering/RenderPipelineAsset.h"
namespace XCEngine {
namespace Rendering {
namespace {
RenderSurface ConfigureFullscreenStageSurface(
const FullscreenPassSurfaceCache::SurfaceEntry& entry,
const RenderSurface& templateSurface,
bool copyDepthAttachment) {
RenderSurface surface = entry.surface;
if (copyDepthAttachment) {
surface.SetDepthAttachment(templateSurface.GetDepthAttachment());
if (templateSurface.HasClearColorOverride()) {
surface.SetClearColorOverride(templateSurface.GetClearColorOverride());
}
}
if (templateSurface.HasCustomRenderArea()) {
surface.SetRenderArea(templateSurface.GetRenderArea());
} else {
surface.ResetRenderArea();
}
surface.SetColorStateBefore(RHI::ResourceStates::Common);
surface.SetColorStateAfter(RHI::ResourceStates::PixelShaderResource);
return surface;
}
} // namespace
SceneRenderer::SceneRenderer() = default;
SceneRenderer::SceneRenderer(std::unique_ptr<RenderPipeline> pipeline)
@@ -37,7 +65,7 @@ std::vector<CameraRenderRequest> SceneRenderer::BuildRenderRequests(
std::vector<CameraRenderRequest> requests =
m_requestPlanner.BuildRequests(scene, overrideCamera, context, surface);
ResolveCameraFinalColorPolicies(requests);
AttachCameraPostProcessRequests(context, requests);
AttachFullscreenStageRequests(context, requests);
return requests;
}
@@ -78,17 +106,19 @@ bool SceneRenderer::Render(
return Render(BuildRenderRequests(scene, overrideCamera, context, surface));
}
void SceneRenderer::PrepareOwnedCameraPostProcessState(size_t requestCount) {
void SceneRenderer::PrepareOwnedFullscreenStageState(size_t requestCount) {
m_ownedPostProcessSequences.clear();
m_ownedPostProcessSequences.resize(requestCount);
m_ownedFinalOutputSequences.clear();
m_ownedFinalOutputSequences.resize(requestCount);
if (m_ownedPostProcessSourceSurfaces.size() < requestCount) {
m_ownedPostProcessSourceSurfaces.resize(requestCount);
if (m_ownedFullscreenStageSurfaces.size() < requestCount) {
m_ownedFullscreenStageSurfaces.resize(requestCount);
}
for (size_t index = 0; index < requestCount; ++index) {
if (m_ownedPostProcessSourceSurfaces[index] == nullptr) {
m_ownedPostProcessSourceSurfaces[index] = std::make_unique<FullscreenPassSurfaceCache>();
if (m_ownedFullscreenStageSurfaces[index] == nullptr) {
m_ownedFullscreenStageSurfaces[index] = std::make_unique<FullscreenPassSurfaceCache>();
}
}
}
@@ -111,10 +141,10 @@ void SceneRenderer::ResolveCameraFinalColorPolicies(
}
}
void SceneRenderer::AttachCameraPostProcessRequests(
void SceneRenderer::AttachFullscreenStageRequests(
const RenderContext& context,
std::vector<CameraRenderRequest>& requests) {
PrepareOwnedCameraPostProcessState(requests.size());
PrepareOwnedFullscreenStageState(requests.size());
for (size_t index = 0; index < requests.size(); ++index) {
CameraRenderRequest& request = requests[index];
@@ -124,8 +154,16 @@ void SceneRenderer::AttachCameraPostProcessRequests(
continue;
}
const CameraPostProcessStack& postProcessPasses = request.camera->GetPostProcessPasses();
if (postProcessPasses.empty()) {
std::unique_ptr<RenderPassSequence> postProcessSequence =
BuildCameraPostProcessPassSequence(request.camera->GetPostProcessPasses());
std::unique_ptr<RenderPassSequence> finalOutputSequence =
BuildFinalColorPassSequence(request.finalColorPolicy);
const bool hasPostProcess =
postProcessSequence != nullptr && postProcessSequence->GetPassCount() > 0u;
const bool hasFinalOutput =
finalOutputSequence != nullptr && finalOutputSequence->GetPassCount() > 0u;
if (!hasPostProcess && !hasFinalOutput) {
continue;
}
@@ -135,45 +173,54 @@ void SceneRenderer::AttachCameraPostProcessRequests(
continue;
}
FullscreenPassSurfaceCache* sourceSurfaceCache = m_ownedPostProcessSourceSurfaces[index].get();
if (sourceSurfaceCache == nullptr ||
!sourceSurfaceCache->EnsureSurfaces(
const size_t fullscreenSurfaceCount = hasPostProcess && hasFinalOutput ? 2u : 1u;
FullscreenPassSurfaceCache* surfaceCache = m_ownedFullscreenStageSurfaces[index].get();
if (surfaceCache == nullptr ||
!surfaceCache->EnsureSurfaces(
context,
request.surface.GetWidth(),
request.surface.GetHeight(),
colorFormat,
1u)) {
fullscreenSurfaceCount)) {
continue;
}
const FullscreenPassSurfaceCache::SurfaceEntry* sourceEntry = sourceSurfaceCache->GetSurfaceEntry(0u);
if (sourceEntry == nullptr || sourceEntry->shaderResourceView == nullptr) {
const FullscreenPassSurfaceCache::SurfaceEntry* sceneColorEntry = surfaceCache->GetSurfaceEntry(0u);
if (sceneColorEntry == nullptr || sceneColorEntry->shaderResourceView == nullptr) {
continue;
}
std::unique_ptr<RenderPassSequence> postProcessSequence =
BuildCameraPostProcessPassSequence(postProcessPasses);
if (postProcessSequence == nullptr || postProcessSequence->GetPassCount() == 0u) {
const FullscreenPassSurfaceCache::SurfaceEntry* postProcessOutputEntry =
hasPostProcess && hasFinalOutput ? surfaceCache->GetSurfaceEntry(1u) : nullptr;
if (hasPostProcess && hasFinalOutput &&
(postProcessOutputEntry == nullptr || postProcessOutputEntry->shaderResourceView == nullptr)) {
continue;
}
RenderSurface sourceSurface = sourceEntry->surface;
sourceSurface.SetDepthAttachment(request.surface.GetDepthAttachment());
sourceSurface.SetColorStateBefore(RHI::ResourceStates::Common);
sourceSurface.SetColorStateAfter(RHI::ResourceStates::PixelShaderResource);
if (request.surface.HasCustomRenderArea()) {
sourceSurface.SetRenderArea(request.surface.GetRenderArea());
} else {
sourceSurface.ResetRenderArea();
}
if (request.surface.HasClearColorOverride()) {
sourceSurface.SetClearColorOverride(request.surface.GetClearColorOverride());
if (hasPostProcess) {
request.postProcess.sourceSurface =
ConfigureFullscreenStageSurface(*sceneColorEntry, request.surface, true);
request.postProcess.sourceColorView = sceneColorEntry->shaderResourceView;
request.postProcess.destinationSurface =
hasFinalOutput
? ConfigureFullscreenStageSurface(*postProcessOutputEntry, request.surface, false)
: request.surface;
m_ownedPostProcessSequences[index] = std::move(postProcessSequence);
request.postProcess.passes = m_ownedPostProcessSequences[index].get();
}
request.postProcess.sourceSurface = sourceSurface;
request.postProcess.sourceColorView = sourceEntry->shaderResourceView;
request.postProcess.destinationSurface = request.surface;
m_ownedPostProcessSequences[index] = std::move(postProcessSequence);
request.postProcess.passes = m_ownedPostProcessSequences[index].get();
if (hasFinalOutput) {
const FullscreenPassSurfaceCache::SurfaceEntry* finalOutputSourceEntry =
hasPostProcess ? postProcessOutputEntry : sceneColorEntry;
request.finalOutput.sourceSurface =
hasPostProcess
? request.postProcess.destinationSurface
: ConfigureFullscreenStageSurface(*sceneColorEntry, request.surface, true);
request.finalOutput.sourceColorView = finalOutputSourceEntry->shaderResourceView;
request.finalOutput.destinationSurface = request.surface;
m_ownedFinalOutputSequences[index] = std::move(finalOutputSequence);
request.finalOutput.passes = m_ownedFinalOutputSequences[index].get();
}
}
}