9.3 KiB
Renderer 当前阶段正式收口计划
日期:2026-04-09
1. 文档定位
这份计划只处理当前 Rendering 主线里“已经能跑,但还没有完全正式化”的问题。
它不是下一阶段功能规划,也不是 SRP / RenderGraph / 后处理体系扩展 计划。
本轮目标很明确:
- 把当前内建渲染链路收口到可长期维护的正式状态。
- 清掉仍然明显带有阶段性、硬编码、单后端假设的实现。
- 在不破坏现有 Editor/Game/Integration Test 行为的前提下,把当前渲染层的边界整理干净。
2. 当前阶段判断
当前 Rendering 已经完成了这些关键闭环:
- 内建前向主链路已经能稳定驱动
Scene / Game视图。 - 多光源、方向光阴影、天空盒、体积渲染都已经进入正式运行链路。
- Shader/Material 资产链路已经从旧散装方案收束到当前统一体系。
- Picking、Outline、Grid、Gizmo 等编辑器侧能力已经具备基本可用性。
- 集成测试体系已经覆盖了一批真实渲染场景,并能做 GT 对比。
但现在还剩下一批很典型的“阶段尾巴”:
- 前向管线对颜色目标格式、深度格式、PSO 组合键仍有硬编码假设。
- Editor 相关 pass 仍夹带单后端假设和格式写死问题。
- 阴影规划层仍偏固定策略,缺少正式配置入口和更清晰的职责边界。
- ObjectId 方案仍是阶段版实现,和
GameObject::ID的长期契约没有彻底收束。 FinalColor与体积渲染之间还有“接口预留已存在,但运行时接线未完全正式化”的问题。
这些问题现在不处理,后面做 SRP、Renderer 扩展、Editor 深化时会持续反噬。
3. 本轮明确不做什么
为了避免计划失控,本轮明确不做下面这些事:
- 不引入
RenderGraph。 - 不启动
SRP正式实现。 - 不重写现有多 pass 框架。
- 不扩展新的大特性,例如延迟渲染、反射探针、后处理栈。
- 不再重开一轮 Shader/Material 语法设计。
本轮只做“把当前链路做正式”。
4. 收口目标
本轮收口完成后,当前 Renderer 至少应满足下面这些条件:
- 同一套内建前向链路不再偷偷依赖固定颜色格式或固定深度格式。
- PSO 缓存键和 pass 描述能完整反映真正影响渲染状态的维度。
- Editor overlay 类 pass 不再用 D3D12 风格思维写死输入输出资源契约。
- 阴影规划和 ObjectId 编码拥有清晰、稳定、可扩展的正式边界。
FinalColor、体积渲染、场景颜色输出之间的职责关系明确且可测试。- 对应单测与集成测试补齐,保证本轮收口不会把现有功能打坏。
5. 分阶段执行
Phase 1:前向管线资源契约正式化
目标:
把当前 BuiltinForwardPipeline 从“能用”整理成“目标格式、深度格式、状态组合都明确受描述驱动”。
要做的事:
- 审查并收口前向主链路里所有颜色目标格式、深度格式、MSAA、load/store、viewport/scissor 的隐式假设。
- 补全 PSO cache key,让真正影响管线状态的维度全部进入键值,而不是靠调用点默认一致。
- 把 render target/depth format 的来源统一到正式 request/context,而不是散落在 pass 内部硬编码。
- 检查
Scene / Game / Editor overlay是否共用了不该共用的隐式默认值,逐一拆开。
优先关注:
engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cppengine/src/Rendering/Pipelines/BuiltinForwardPipelineResources.cpp- 与 camera request / pass context / pipeline key 相关的描述结构
验收标准:
- 同一前向主链路可在不同颜色格式/深度格式输入下保持行为正确。
- 不再存在“只因为默认值碰巧一致所以能跑”的路径。
- 相关单测补齐并通过。
Phase 2:Editor Overlay Pass 正式化
目标:
把 Grid / Outline / ObjectId 这批 Editor 侧 pass 从阶段性实现整理成正式 pass。
要做的事:
- 审查
BuiltinInfiniteGridPass、BuiltinSelectionOutlinePass、BuiltinObjectIdOutlinePass对资源格式和后端行为的假设。 - 把这些 pass 对 scene color/depth/object-id/mask 的输入输出契约整理成统一描述,而不是各自单独偷拿默认格式。
- 去掉明显的 D3D12-only 思维残留,至少保证代码层面不再把后端差异写死在 pass 逻辑里。
- 统一调试路径和正式路径,避免同一个 pass 同时保留多套阶段性资源接法。
优先关注:
engine/src/Rendering/Passes/BuiltinInfiniteGridPass.cppengine/src/Rendering/Passes/BuiltinSelectionOutlinePass.cppengine/src/Rendering/Passes/BuiltinObjectIdOutlinePass.cpp- Editor 侧 Scene/Game viewport render target 管理层
验收标准:
- Grid、Outline、Picking 对资源输入输出的依赖关系清晰可读。
- Editor 相关 pass 不再依赖单后端硬编码格式。
- 现有 Scene/Game 视图行为不回退。
Phase 3:Shadow Planning 与 ObjectId 正式边界收口
目标:
把当前“能工作但还是阶段实现”的阴影规划与 ObjectId 方案整理为正式边界。
要做的事:
- 审查方向光阴影规划层,把固定
1024阴影图尺寸、全场景粗扫描等阶段策略抽成正式配置/策略点。 - 明确 shadow request/planning/execution 的职责边界,避免 planner 继续膨胀成杂物层。
- 审查
ObjectIdCodec与GameObject::ID关系。 - 明确长期方案到底是稳定 32-bit 渲染 ID,还是正式的 runtime 映射表,不再让 64-bit 对象 ID 与 32-bit object-id target 处于半耦合状态。
- 为 picking、outline、editor selection 使用同一份正式 ID 契约。
优先关注:
engine/src/Rendering/Planning/SceneRenderRequestPlanner.cppengine/include/XCEngine/Rendering/Picking/ObjectIdCodec.hengine/include/XCEngine/Components/GameObject.h
验收标准:
- 阴影规划不再带有明显的固定阶段参数硬编码。
- ObjectId 编码边界清晰且有测试覆盖。
- Picking/Outline 不再建立在模糊 ID 约定之上。
Phase 4:FinalColor 与体积渲染接线正式化
目标:
把当前 FinalColor、场景颜色输出、体积渲染之间的关系做实,避免继续停留在“API 预留了,但接线没完全正式化”的状态。
要做的事:
- 复查
FinalColorSettings、camera request、scene renderer 执行链路中的实际生效路径。 - 确认 volume override / final color override 的职责边界,是正式运行时能力还是仅作为未来扩展保留。
- 把现在已经真实存在的行为和仍只是预留的行为区分清楚。
- 如果保留预留接口,就必须让默认行为、空行为、调试行为全部明确;如果决定正式启用,就把运行时接线补齐。
优先关注:
engine/include/XCEngine/Rendering/Planning/FinalColorSettings.hengine/src/Rendering/Execution/SceneRenderer.cpp- 与 camera scene renderer / frame composition 相关的执行层
验收标准:
FinalColor不再停留在“名字像正式能力,实际只是半接线状态”。- 体积渲染与最终颜色输出关系清晰、行为稳定。
- 对应单测或场景回归测试补齐。
Phase 5:测试、文档、归档收口
目标:
让这一轮不是“代码上看起来做完”,而是真正可交接、可回归、可归档。
要做的事:
- 为本轮所有正式化改动补对应 unit/integration coverage。
- 至少复跑当前关键 Rendering 集成场景:
- 基础 forward 场景
- directional shadow 场景
- skybox 场景
- volume 场景
- 更新必要文档,把本轮完成的阶段计划归档到
docs/used。 - 输出一份阶段总结,明确当前 Renderer 已正式化到什么程度,下一阶段才该进入什么主题。
验收标准:
- 关键测试全绿。
- 没有新增“只在某个后端偶然能过”的脆弱实现。
- 本轮计划可以被完整归档。
6. 执行顺序要求
必须按下面顺序推进:
- 先做
Phase 1 - 再做
Phase 2 - 然后做
Phase 3 - 再处理
Phase 4 - 最后统一做
Phase 5收口
原因很简单:
- 前向主链路资源契约不稳,后面的 Editor pass 正式化会一直返工。
- ObjectId 和 shadow planning 的正式边界不先理顺,Editor 相关能力会持续建立在临时假设上。
FinalColor的运行时接线要建立在前面这些边界已经收紧之后。
7. 本轮完成标志
当下面条件同时成立时,这一轮 Renderer 收口才算真正完成:
- 当前内建前向链路已摆脱明显格式硬编码和状态隐式约定。
- Editor overlay 类 pass 已完成正式资源契约整理。
- Shadow planning 与 ObjectId 契约已从阶段版实现收口为正式边界。
FinalColor与体积渲染关系已经明确并落地到代码与测试。- 所有本轮阶段性计划文档已经归档,
docs/plan中不再残留已经完成的旧专项计划。
8. 一句话结论
当前 Renderer 已经具备“继续承接更高层系统”的能力,但在进入下一阶段之前,必须先把资源契约、Editor pass、阴影规划、ObjectId、FinalColor 这五块彻底做正式;这轮收口做完,后面再接 SRP 或更复杂渲染能力才不会反复返工。