From 4debbbea1f8e19bdab697f3dafff4d099c290126 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Fri, 10 Apr 2026 01:21:00 +0800 Subject: [PATCH] Tighten final color contract --- ...余收口与体积渲染多后端正式化计划_2026-04-10.md | 12 +++++------- .../Rendering/Planning/FinalColorSettings.h | 9 +-------- engine/src/Rendering/Execution/SceneRenderer.cpp | 15 +++++++++++++-- .../Rendering/unit/test_camera_scene_renderer.cpp | 1 - 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/docs/plan/Renderer剩余收口与体积渲染多后端正式化计划_2026-04-10.md b/docs/plan/Renderer剩余收口与体积渲染多后端正式化计划_2026-04-10.md index 453186d6..f4fb2ab5 100644 --- a/docs/plan/Renderer剩余收口与体积渲染多后端正式化计划_2026-04-10.md +++ b/docs/plan/Renderer剩余收口与体积渲染多后端正式化计划_2026-04-10.md @@ -12,7 +12,7 @@ 本轮目标有且只有四类: 1. 把 NanoVDB 体积渲染从 D3D12 单后端正式能力推进到 Vulkan / OpenGL 正式能力。 -2. 把 `FinalColor` 与 volume/final-output 的契约收死,消除“接口已存在但运行时半接线”的状态。 +2. 把 `FinalColor` 与 final-output 的契约收死,消除“接口已存在但运行时半接线”的状态。 3. 把 `ObjectId` 从“低 32 位截断可用方案”推进到清晰稳定的正式渲染 ID 契约。 4. 把阴影规划与前向管线剩余的硬编码策略、monolith 结构继续拆干净。 @@ -23,7 +23,7 @@ 当前 Rendering 已经具备稳定运行基础,但还不能称为“完全收口”,核心原因是: 1. `volume_scene / volume_occlusion_scene / volume_transform_scene` 目前仍只在 D3D12 上做了正式实例化与 GT 验证。 -2. `FinalColorSettings` 已经具备 pipeline/camera/volume 三层策略接口,但运行时只真正接入了 pipeline + camera。 +2. `FinalColorSettings` 当前真正落地的是 pipeline defaults + camera overrides;此前残留的 volume override 分支只是头文件级 API,并未进入运行时。 3. `ObjectId` 仍基于 runtime object id 低 32 位编码,不是长期正式方案。 4. `SceneRenderRequestPlanner` 里仍保留方向光阴影尺寸与 focus 策略的硬编码。 5. `BuiltinForwardPipeline` 功能上可用,但资源布局、PSO、descriptor、skybox、draw path 仍聚集在同一条大实现链里。 @@ -92,12 +92,10 @@ 任务: -1. 审查 `FinalColorSettings`、camera overrides、volume overrides 的设计边界。 -2. 二选一处理 volume override: - - 真正接入运行时解析链路; - - 或明确从现阶段 API 中收掉,不再保留半接线接口。 +1. 审查 `FinalColorSettings`、camera overrides、final-output 的设计边界。 +2. 将未落地的 volume override 分支从现阶段 API 中正式收掉,不再保留半接线接口。 3. 补齐对应单测与场景回归测试。 -4. 明确 post-process / final-output / volume 的职责关系文档。 +4. 明确 post-process / final-output 的职责关系文档。 验收标准: diff --git a/engine/include/XCEngine/Rendering/Planning/FinalColorSettings.h b/engine/include/XCEngine/Rendering/Planning/FinalColorSettings.h index c9e3b82f..16473ef0 100644 --- a/engine/include/XCEngine/Rendering/Planning/FinalColorSettings.h +++ b/engine/include/XCEngine/Rendering/Planning/FinalColorSettings.h @@ -66,7 +66,6 @@ struct FinalColorOverrideSettings { struct ResolvedFinalColorPolicy : FinalColorSettings { bool hasPipelineDefaults = false; bool hasCameraOverrides = false; - bool hasVolumeOverrides = false; }; inline void ApplyFinalColorOverrides( @@ -95,8 +94,7 @@ inline void ApplyFinalColorOverrides( inline ResolvedFinalColorPolicy ResolveFinalColorPolicy( const FinalColorSettings& pipelineDefaults, - const FinalColorOverrideSettings* cameraOverrides = nullptr, - const FinalColorOverrideSettings* volumeOverrides = nullptr) { + const FinalColorOverrideSettings* cameraOverrides = nullptr) { ResolvedFinalColorPolicy resolved = {}; resolved.outputTransferMode = pipelineDefaults.outputTransferMode; resolved.exposureMode = pipelineDefaults.exposureMode; @@ -110,11 +108,6 @@ inline ResolvedFinalColorPolicy ResolveFinalColorPolicy( resolved.hasCameraOverrides = true; } - if (volumeOverrides != nullptr && volumeOverrides->HasOverrides()) { - ApplyFinalColorOverrides(*volumeOverrides, resolved); - resolved.hasVolumeOverrides = true; - } - return resolved; } diff --git a/engine/src/Rendering/Execution/SceneRenderer.cpp b/engine/src/Rendering/Execution/SceneRenderer.cpp index 1d7d2ff8..7b866b9e 100644 --- a/engine/src/Rendering/Execution/SceneRenderer.cpp +++ b/engine/src/Rendering/Execution/SceneRenderer.cpp @@ -1,6 +1,7 @@ #include "Rendering/Execution/SceneRenderer.h" #include "Components/CameraComponent.h" +#include "Debug/Logger.h" #include "Rendering/Caches/FullscreenPassSurfaceCache.h" #include "Rendering/Planning/CameraPostProcessPassFactory.h" #include "Rendering/Planning/FinalColorPassFactory.h" @@ -19,6 +20,8 @@ RenderSurface ConfigureFullscreenStageSurface( RenderSurface surface = entry.surface; if (copyDepthAttachment) { surface.SetDepthAttachment(templateSurface.GetDepthAttachment()); + surface.SetDepthStateBefore(templateSurface.GetDepthStateBefore()); + surface.SetDepthStateAfter(templateSurface.GetDepthStateAfter()); if (templateSurface.HasClearColorOverride()) { surface.SetClearColorOverride(templateSurface.GetClearColorOverride()); } @@ -175,8 +178,7 @@ void SceneRenderer::ResolveCameraFinalColorPolicies( request.finalColorPolicy = ResolveFinalColorPolicy( pipelineDefaults, - &request.camera->GetFinalColorOverrides(), - nullptr); + &request.camera->GetFinalColorOverrides()); } } @@ -206,6 +208,13 @@ void SceneRenderer::AttachFullscreenStageRequests( continue; } + if (request.surface.GetSampleCount() > 1u) { + Debug::Logger::Get().Error( + Debug::LogCategory::Rendering, + "SceneRenderer fullscreen post-process/final-output chain currently requires a single-sample main scene surface"); + continue; + } + const std::vector& colorAttachments = request.surface.GetColorAttachments(); const RHI::Format colorFormat = colorAttachments[0]->GetFormat(); if (colorFormat == RHI::Format::Unknown) { @@ -240,6 +249,7 @@ void SceneRenderer::AttachFullscreenStageRequests( request.postProcess.sourceSurface = ConfigureFullscreenStageSurface(*sceneColorEntry, request.surface, true); request.postProcess.sourceColorView = sceneColorEntry->shaderResourceView; + request.postProcess.sourceColorState = request.postProcess.sourceSurface.GetColorStateAfter(); request.postProcess.destinationSurface = hasFinalOutput ? ConfigureFullscreenStageSurface(*postProcessOutputEntry, request.surface, false) @@ -256,6 +266,7 @@ void SceneRenderer::AttachFullscreenStageRequests( ? request.postProcess.destinationSurface : ConfigureFullscreenStageSurface(*sceneColorEntry, request.surface, true); request.finalOutput.sourceColorView = finalOutputSourceEntry->shaderResourceView; + request.finalOutput.sourceColorState = request.finalOutput.sourceSurface.GetColorStateAfter(); request.finalOutput.destinationSurface = request.surface; m_ownedFinalOutputSequences[index] = std::move(finalOutputSequence); request.finalOutput.passes = m_ownedFinalOutputSequences[index].get(); diff --git a/tests/Rendering/unit/test_camera_scene_renderer.cpp b/tests/Rendering/unit/test_camera_scene_renderer.cpp index 692140e9..d8b4c985 100644 --- a/tests/Rendering/unit/test_camera_scene_renderer.cpp +++ b/tests/Rendering/unit/test_camera_scene_renderer.cpp @@ -2026,7 +2026,6 @@ TEST(SceneRenderer_Test, ResolvesFinalColorPolicyFromPipelineDefaultsAndCameraOv const CameraRenderRequest& request = requests[0]; EXPECT_TRUE(request.finalColorPolicy.hasPipelineDefaults); EXPECT_TRUE(request.finalColorPolicy.hasCameraOverrides); - EXPECT_FALSE(request.finalColorPolicy.hasVolumeOverrides); EXPECT_EQ( request.finalColorPolicy.outputTransferMode, FinalColorOutputTransferMode::LinearToSRGB);