Plan post-process and final-output closure
This commit is contained in:
@@ -0,0 +1,296 @@
|
||||
# Renderer 当前主线下一阶段:PostProcess 与 FinalOutput 收口计划
|
||||
|
||||
日期:`2026-04-06`
|
||||
|
||||
## 1. 阶段结论
|
||||
|
||||
当前 Rendering 主线的下一个阶段,不应该跳去做:
|
||||
|
||||
- `render graph`
|
||||
- deferred / clustered
|
||||
- GPU picking 替换
|
||||
- 更复杂的 editor-only 特效
|
||||
|
||||
现在真正还没收口的,是 **runtime 相机帧合成链路**。
|
||||
|
||||
更具体地说,就是把当前 renderer 从:
|
||||
|
||||
`Scene -> 直接打到最终 surface`
|
||||
|
||||
收口成:
|
||||
|
||||
`Scene Color -> 可选 PostProcess -> Final Output`
|
||||
|
||||
只有这一步补齐之后,现阶段的 renderer 才算真正具备了稳定的 runtime frame composition 能力,也才适合继续往 Unity 风格的 renderer feature / C# SRP 承接点推进。
|
||||
|
||||
## 2. 为什么现在必须先做这个
|
||||
|
||||
当前仓库已经具备:
|
||||
|
||||
- 正式的 forward runtime scene renderer
|
||||
- directional / point / spot 多光源
|
||||
- main directional shadow
|
||||
- skybox
|
||||
- object id
|
||||
- editor overlay / gizmo / grid
|
||||
|
||||
但真正缺的仍然是下面这条 runtime 正式主链:
|
||||
|
||||
`Opaque -> Skybox -> Transparent -> PostProcess -> Final Output`
|
||||
|
||||
现在的主要缺口是:
|
||||
|
||||
- `CameraRenderRequest` 还没有正式的 post-process / final-output contract
|
||||
- `CameraRenderer` 仍然以 `request.surface` 作为主场景直接输出目标
|
||||
- 没有 renderer 级别的 fullscreen pass 基础设施
|
||||
- 没有“只有需要时才分配 intermediate color target”的正式策略
|
||||
- 也没有一个专门验证 runtime 后处理闭环的 `post_process_scene`
|
||||
|
||||
如果这个阶段不先收口,后续无论做 tone mapping、color grading、exposure、更多环境特性,都会继续以临时拼接的方式往上堆,架构会重新变脏。
|
||||
|
||||
## 3. 目标
|
||||
|
||||
本阶段只做一件事:
|
||||
|
||||
**把 runtime 相机输出链路正式化。**
|
||||
|
||||
完成后应达到:
|
||||
|
||||
1. renderer 具备正式的 post-process 请求与执行入口。
|
||||
2. renderer 具备 backend-neutral 的 fullscreen pass 基础设施。
|
||||
3. 相机默认仍可直接渲染到最终目标,只有在确实需要后处理或最终合成时才切换 intermediate color target。
|
||||
4. final output 的 copy / blit / resolve 规则明确,不再隐式散落在具体 pass 中。
|
||||
5. object id 与 editor overlay 明确保持在 runtime final-color 主链之外。
|
||||
6. 增加 `post_process_scene` 集成测试,验证三后端一致性。
|
||||
|
||||
## 4. 非目标
|
||||
|
||||
本阶段明确不做:
|
||||
|
||||
- `render graph`
|
||||
- HDR 全量管线
|
||||
- bloom / SSAO / DOF / motion blur 等完整后处理套件
|
||||
- cubemap IBL / reflection probe
|
||||
- GPU picking 替换 CPU picking
|
||||
- editor SceneView 的额外视觉增强
|
||||
- 新一轮 renderer 大重构
|
||||
|
||||
## 5. 设计原则
|
||||
|
||||
### 5.1 继续遵循当前分层
|
||||
|
||||
- `RHI` 只提供资源、render target、pipeline、draw/dispatch 抽象。
|
||||
- `Renderer` 负责相机帧规划、runtime pass 调度、final output 规则。
|
||||
- `Editor` 仍然只是宿主与 overlay 使用方,不接管 runtime 后处理。
|
||||
|
||||
### 5.2 runtime 主链与 editor 辅助链继续隔离
|
||||
|
||||
下列内容不进入 runtime final-color 主链:
|
||||
|
||||
- `ObjectId`
|
||||
- grid
|
||||
- gizmo
|
||||
- selection outline
|
||||
- scene icon
|
||||
|
||||
它们仍然属于 editor 专用辅助链路。
|
||||
|
||||
### 5.3 默认直出,按需离屏
|
||||
|
||||
默认情况:
|
||||
|
||||
- 没有 post-process
|
||||
- 没有额外 final composition 需求
|
||||
|
||||
则继续允许相机直接渲染到最终 `surface`。
|
||||
|
||||
只有满足下面条件之一时,才启用 intermediate color target:
|
||||
|
||||
- 存在 runtime post-process
|
||||
- final output 需要一次 fullscreen copy / resolve / color transform
|
||||
- 后续扩展的 runtime frame composition 明确要求 scene color 先落到中间目标
|
||||
|
||||
这个判断必须由 `CameraRenderer` 或 request planning 统一控制,不能散落到单个 pass 内部。
|
||||
|
||||
## 6. 核心方案
|
||||
|
||||
### 6.1 补齐 CameraRenderRequest 的正式 contract
|
||||
|
||||
当前 `CameraRenderRequest` 已有:
|
||||
|
||||
- `PreScenePasses`
|
||||
- `ShadowCaster`
|
||||
- `DepthOnly`
|
||||
- `MainScene`
|
||||
- `ObjectId`
|
||||
- `PostScenePasses`
|
||||
- `OverlayPasses`
|
||||
|
||||
下一步要补的是“runtime final-color 链”的明确语义,而不是继续把 `PostScenePasses` 当一个模糊兜底桶。
|
||||
|
||||
建议演进方向:
|
||||
|
||||
- 保留现有 stage 枚举兼容当前结构
|
||||
- 在 request 数据层新增更明确的 runtime 输出描述
|
||||
- 显式区分:
|
||||
- scene color source
|
||||
- post-process chain
|
||||
- final output target
|
||||
|
||||
换句话说,本阶段的重点不是改名字,而是把数据契约补完整。
|
||||
|
||||
### 6.2 增加 Fullscreen Pass 基础设施
|
||||
|
||||
需要新增 backend-neutral 的 fullscreen pass helper,用于:
|
||||
|
||||
- 绑定 source color texture
|
||||
- 绑定 sampler / descriptor set
|
||||
- 设置 fullscreen triangle 或等价路径
|
||||
- 输出到指定 color target
|
||||
|
||||
首版要求:
|
||||
|
||||
- 三后端可复用同一套 renderer 侧调用方式
|
||||
- shader 输入输出约束简单、稳定、可测试
|
||||
- 不依赖 editor 私有绘制路径
|
||||
|
||||
### 6.3 Final Output 明确化
|
||||
|
||||
当前 main scene 直接打到 `request.surface` 的方式,需要升级成可判断的策略:
|
||||
|
||||
1. 如果本帧不需要 post-process / final copy,则 direct-to-surface。
|
||||
2. 如果本帧需要 post-process,则:
|
||||
- main scene 输出到 intermediate color target
|
||||
- post-process 读取 intermediate
|
||||
- final pass 输出到 `request.surface`
|
||||
|
||||
这里要把以下规则写死:
|
||||
|
||||
- intermediate 的格式、尺寸与生命周期
|
||||
- final blit / copy / fullscreen draw 由谁负责
|
||||
- MSAA / resolve 如果暂时没有正式支持,要在 contract 里先写清当前限制
|
||||
|
||||
### 6.4 第一阶段验证效果只做最小闭环
|
||||
|
||||
本阶段不追求复杂后处理效果。
|
||||
|
||||
第一阶段 builtin effect 建议只做一种确定性极强、三后端最容易对齐的效果:
|
||||
|
||||
- `ColorScale`
|
||||
|
||||
例如对 scene color 统一乘一个常量因子。
|
||||
|
||||
这样做的原因:
|
||||
|
||||
- 易于写 GT
|
||||
- 不依赖复杂数学或 LUT
|
||||
- 不容易受不同后端精度差异影响
|
||||
- 能直接证明 post-process infrastructure 已闭环
|
||||
|
||||
## 7. 测试策略
|
||||
|
||||
### 7.1 新增集成测试
|
||||
|
||||
新增:
|
||||
|
||||
- `tests/Rendering/integration/post_process_scene`
|
||||
|
||||
建议测试场景:
|
||||
|
||||
- 结构尽量简单
|
||||
- 使用确定性颜色块或单个模型
|
||||
- 主场景颜色在经过 `ColorScale` 后能明显与未处理版本区分
|
||||
- 三后端都输出 `*_d3d12.ppm` / `*_opengl.ppm` / `*_vulkan.ppm`
|
||||
- 统一对比单张 `GT.ppm`
|
||||
|
||||
### 7.2 必跑回归
|
||||
|
||||
本阶段至少回归:
|
||||
|
||||
- `rendering_integration_skybox_scene`
|
||||
- `rendering_integration_offscreen_scene`
|
||||
- `rendering_integration_transparent_material_scene`
|
||||
- `rendering_integration_camera_stack_scene`
|
||||
- `rendering_integration_object_id_scene`
|
||||
|
||||
必要时再补:
|
||||
|
||||
- `material_state_scene`
|
||||
- `depth_sort_scene`
|
||||
|
||||
### 7.3 单测方向
|
||||
|
||||
建议补或增强的 unit coverage:
|
||||
|
||||
- 何时启用 intermediate color target
|
||||
- post-process chain 为空时的 direct path
|
||||
- final output routing 决策
|
||||
- request contract 的默认行为与 fallback
|
||||
|
||||
## 8. 分阶段执行
|
||||
|
||||
### Phase A:补齐 contract
|
||||
|
||||
目标:
|
||||
|
||||
- 明确 runtime post-process / final-output 所需的数据结构与决策入口
|
||||
|
||||
完成标准:
|
||||
|
||||
- `CameraRenderRequest` / planner / `CameraRenderer` 层的数据语义清晰
|
||||
- 现有场景渲染不回退
|
||||
|
||||
### Phase B:引入 fullscreen pass 与 intermediate 策略
|
||||
|
||||
目标:
|
||||
|
||||
- 跑通 scene color -> fullscreen pass -> final surface
|
||||
|
||||
完成标准:
|
||||
|
||||
- 三后端都能稳定执行最小 fullscreen pass
|
||||
- direct path 仍然保留
|
||||
|
||||
### Phase C:接入最小 builtin post-process
|
||||
|
||||
目标:
|
||||
|
||||
- 用 `ColorScale` 验证 runtime 后处理闭环
|
||||
|
||||
完成标准:
|
||||
|
||||
- `post_process_scene` GT 通过
|
||||
- `skybox_scene` / `offscreen_scene` / `transparent_material_scene` 不回退
|
||||
|
||||
### Phase D:文档与测试收口
|
||||
|
||||
目标:
|
||||
|
||||
- 把当前阶段的 contract、测试矩阵、限制条件写回文档
|
||||
|
||||
完成标准:
|
||||
|
||||
- `tests/TEST_SPEC.md` 如有必要同步更新
|
||||
- 当前计划可归档到 `docs/used`
|
||||
|
||||
## 9. 收口判定
|
||||
|
||||
满足以下条件时,本阶段可以视为完成:
|
||||
|
||||
1. runtime renderer 已具备正式 post-process 入口。
|
||||
2. final output 路径不再依赖隐式直写逻辑。
|
||||
3. intermediate color target 为按需启用,而不是一刀切常驻。
|
||||
4. `post_process_scene` 在 D3D12 / OpenGL / Vulkan 三后端通过。
|
||||
5. `skybox_scene`、`offscreen_scene`、`camera_stack_scene`、`transparent_material_scene` 不回退。
|
||||
6. object id 与 editor overlay 没有被错误卷入 runtime final-color 链。
|
||||
|
||||
## 10. 这一阶段之后再做什么
|
||||
|
||||
等这一阶段收口之后,renderer 主线再继续往下走,顺序才是合理的:
|
||||
|
||||
1. 更正式的 shader / material runtime pass contract
|
||||
2. 更成熟的 renderer feature / Unity 风格可扩展点
|
||||
3. GPU object id / picking 正式化
|
||||
4. 更复杂的 environment、tone mapping 与后处理能力
|
||||
|
||||
也就是说,**现在下一步不是做更多“效果”,而是先把相机输出主链做完整。**
|
||||
Reference in New Issue
Block a user