Archive multi-light plan and draft next renderer phase

This commit is contained in:
2026-04-05 17:23:50 +08:00
parent a94b005b76
commit 97f7c26eff
2 changed files with 938 additions and 0 deletions

View File

@@ -0,0 +1,412 @@
# Renderer 下一阶段Skybox 环境与 Frame Composition 正式化计划
日期:`2026-04-05`
## 1. 阶段定位
多光源 forward runtime 这一阶段已经闭环:
- `Directional / Point / Spot` 已接入正式 lighting contract
- `main directional shadow` 已保持稳定
- 三后端 lighting integration 已有完整回归矩阵
- Scene / Game View 已复用同一条 runtime renderer 主链
因此 renderer 主线现在不应该继续停留在“补光照地基”,而应该进入下一阶段:
**把当前 renderer 从“单次场景绘制”推进成“正式的相机帧合成框架”,先补齐 `Opaque -> Skybox -> Transparent -> PostProcess -> Final Output` 这条主链。**
这一步完成后rendering 主线才算真正具备继续承接:
- skybox / environment
- 正式后处理入口
- 更稳定的 camera output composition
- 后续 Unity 风格 renderer feature / C# SRP 对接
## 2. 为什么现在必须先做这个
当前 renderer 虽然已经能稳定画出 lit / unlit / shadow / object-id / editor overlay但它还不是完整的相机帧合成体系
- `BuiltinForwardPipeline` 目前本质上还是“一次场景遍历直接打到最终目标”
- 没有正式 `Skybox` 阶段
- 没有正式 `Environment` 数据入口
- 没有 runtime 级别的 `PostProcess` 输入 / 输出约定
- 还没有“只在需要时启用 intermediate color target”的相机合成策略
如果这个阶段不先做,后面不管是:
- 天空盒
- 环境贴图
- 曝光 / 色调映射
- 颜色调整
- 屏幕空间效果
都会继续以临时 pass 拼接的方式往上叠,最后会把当前已经比较干净的 renderer 主链重新拉乱。
## 3. 与 Unity / SRP 对齐的原则
这一阶段继续严格遵守当前工程的核心分层:
- `RHI` 只负责 GPU 抽象,不知道 skybox / environment / post-process 语义
- `Renderer` 负责相机帧规划、scene extraction、frame composition、runtime pass orchestration
- `Editor` 仍然只是 renderer 的宿主和 overlay 使用方
与 Unity 风格保持对齐时,本阶段遵守以下原则:
1. `Skybox / Environment / PostProcess` 都属于 runtime renderer 正式能力,不是 editor 特供逻辑
2. editor 的 grid / gizmo / icon / selection outline 不进入 runtime frame composition 主链
3. 不引入 `render graph`
4. 不直接跳到 deferred / clustered / HDRP 级复杂度
5. 先建立正式 `frame composition seam`,再谈更复杂的 renderer feature
## 4. 当前真实状态
### 4.1 已经具备的基础
- `CameraRenderer` 已有明确的请求装配入口
- `SceneRenderer -> CameraRenderer -> RenderPipeline` 主链稳定
- 已支持:
- `shadowCaster`
- `depthOnly`
- `main pipeline`
- `objectId`
- `overlayPasses`
- `RenderSceneExtractor` 已有稳定的:
- visible item 提取与排序
- main light / additional lights 提取
- `transparent_material_scene``depth_sort_scene``offscreen_scene` 已证明当前透明与离屏基础可用
### 4.2 还没正式化的缺口
- 没有 renderer 级 `Skybox` pass contract
- 没有 `RenderEnvironmentData`
- `BuiltinForwardPipeline` 还没有正式拆分成 `Opaque / Transparent`
- 没有“需要 post-process 时自动切到 intermediate color target”的约定
- 没有 runtime fullscreen pass 基础设施
- 没有证明 `Skybox + Transparent + PostProcess` 同时存在时仍然稳定的 integration coverage
## 5. 本阶段总目标
本阶段只做一件事:
**建立一条正式、稳定、三后端一致、可测试的 camera frame composition 主链。**
收口后应达到:
1. 场景绘制正式分为 `Opaque -> Skybox -> Transparent`
2. renderer 有正式 `Environment` 数据入口
3. renderer 有正式 `PostProcess` 输入 / 输出入口
4. 只在确实需要时才分配 intermediate color target
5. Scene / Game View 继续复用同一条 runtime frame composition 主链
6. 为后续 Unity 风格 renderer feature / C# SRP 留出清晰承接点
## 6. 非目标
本阶段明确不做:
- `render graph`
- deferred rendering
- clustered / tiled lighting
- IBL / reflection probe / light probe
- point / spot shadow
- 全量 post-process 套件
- 完整 HDR pipeline
- editor-only 视觉效果继续扩张
## 7. 设计方案
### 7.1 正式化 Camera Frame Composition
建议把相机级 runtime composition 明确写成固定阶段:
1. `shadowCaster`
2. `depthOnly`(按需求)
3. `opaque scene`
4. `skybox`
5. `transparent scene`
6. `post-process`
7. `final output resolve / blit`
8. `objectId`
9. `overlay`
关键原则:
- `objectId` 继续独立,不混入 runtime final color 主链
- `overlay` 继续是宿主级 / editor 级最后附加层
- runtime 的 `Skybox / PostProcess` 是相机帧的一部分,不应再伪装成 editor overlay
### 7.2 拆分 BuiltinForwardPipeline 的 scene 阶段
当前 `BuiltinForwardPipeline` 虽然能依赖 render queue 正确排序,但 skybox 正式接入后,必须让 runtime scene path 至少具备:
- `OpaquePass`
- `TransparentPass`
原因很直接:
- skybox 必须有正式插入点
- transparent 需要在 skybox 之后
- 以后 post-process 输入也需要明确“scene color 到哪里结束”
这里不需要推翻现有 forward lit / unlit 合约,只需要把当前单次遍历拆成正式两个阶段,并保持现有材质状态和排序行为不回退。
### 7.3 正式化 Environment 数据入口
建议新增 renderer 级环境数据模型,例如:
- `RenderEnvironmentData`
- `clearMode`
- `skyboxMaterial`
- `skyboxEnabled`
- 后续可扩展环境颜色 / 曝光 / cubemap 引用
第一版原则:
1. 先解决“环境如何进入 renderer”
2. 不在这一阶段强行上完整 IBL
3. 不把 environment 设计成 editor 专属状态
### 7.4 Skybox 首版策略
首版建议优先做 **builtin procedural skybox**,而不是一开始就把阶段拖进 cubemap / probe / importer 链路。
理由:
- 目标是先打通正式 `skybox pass`
- procedural skybox 更容易稳定三后端一致
- 更容易写 GT 和像素断言
- 不依赖 cubemap 资源导入闭环
首版可以支持:
- top / horizon / bottom color
- 视线方向驱动的渐变
后续再扩成 cubemap skybox不会推翻本阶段的 frame composition 设计。
### 7.5 Post-Process 正式入口的最小闭环
本阶段不追求“后处理功能多”,只追求“后处理入口正式化”。
建议最小闭环:
1. 建立 fullscreen pass 基础设施
2. 建立 `post-process source -> destination` 约定
3. 建立 intermediate color target 的按需分配策略
4. 用一个简单、稳定、三后端一致的 builtin fullscreen effect 做验证
验证 effect 不需要复杂,建议:
- `ColorTint`
- `GammaAdjust`
- `FinalCopy + optional color scale`
关键不是效果本身,而是证明:
- scene color 能被正式读回
- fullscreen pass 能稳定写到目标
- camera final output 路径已具备后续扩展能力
### 7.6 Intermediate Color Target 策略
不能把所有相机都默认改成“永远先画离屏再 blit”否则会徒增复杂度和性能成本。
建议规则:
- 默认直接渲染到最终目标
- 当存在 `Skybox / PostProcess / 特定 composition 需求` 时,按需启用 intermediate color target
- 这个判断应由 `CameraRenderer` 或 request planner 明确控制,而不是散落在具体 pass 内部
### 7.7 与 Unity 风格 SRP 的承接关系
这一阶段完成后renderer 主链会更接近 Unity/URP 的基本心智模型:
- scene opaque
- skybox
- transparent
- post-process
- final target
这一步不是为了机械模仿 Unity而是为了给以后 C# 层 SRP / renderer feature 建立正确的宿主结构。
## 8. 实施分阶段
## 8.1 Phase AFrame Composition 合约正式化
### 目标
把相机级帧合成顺序从“隐式拼接”改成正式 contract。
### 工作项
- 明确 runtime frame composition 阶段枚举 / 顺序
- 调整 `CameraRenderer` 的 orchestration 结构
- 明确 `objectId``overlay` 与 runtime frame composition 的边界
### 验收标准
- 相机帧阶段顺序明确且可追踪
- 现有 `multi_light / transparent / offscreen` 不回退
## 8.2 Phase BOpaque / Skybox / Transparent 正式分段
### 目标
让 builtin forward runtime scene path 具备正式 `Opaque / Transparent` 结构,并为 skybox 提供插入点。
### 工作项
- 拆分 `BuiltinForwardPipeline`
- 保持现有 render queue 语义
- 保持透明排序与材质状态回归不破坏
### 验收标准
- `transparent_material_scene`
- `depth_sort_scene`
- `material_state_scene`
三后端继续通过
## 8.3 Phase CSkybox / Environment 首版闭环
### 目标
让 renderer 正式支持 runtime skybox。
### 工作项
- 新增 `RenderEnvironmentData`
- 新增 builtin procedural skybox pass / shader
- 将 skybox 接入 camera frame composition
- 保持 clear color fallback 行为可控
### 验收标准
- 新增 `skybox_scene`
- 同时存在 opaque + skybox + transparent 时顺序正确
- 三后端 GT 稳定
## 8.4 Phase DPost-Process 入口闭环
### 目标
建立正式 fullscreen post-process 入口,而不是继续依赖临时 pass。
### 工作项
- fullscreen pass helper
- intermediate color target 按需分配
- final blit / resolve 规则
- 一个最小 builtin post-process 验证效果
### 验收标准
- 新增 `post_process_scene`
- `offscreen_scene` 不回退
- 三后端 GT 稳定
## 8.5 Phase E测试与文档收口
### 目标
让本阶段收口后,`docs/plan` 的主线入口与真实实现再次一致。
### 工作项
- 更新 `tests/TEST_SPEC.md`
- 输出 renderer frame composition 阶段说明
- 将本阶段完成计划归档到 `docs/used`
### 验收标准
- 文档、实现、测试矩阵三者口径一致
## 9. 测试策略
### 9.1 Unit
- frame composition 阶段决策
- intermediate target 启用条件
- skybox / post-process request 装配
### 9.2 Integration
新增:
- `skybox_scene`
- `post_process_scene`
回归:
- `multi_light_scene`
- `spot_light_scene`
- `directional_shadow_scene`
- `camera_stack_scene`
- `transparent_material_scene`
- `cull_material_scene`
- `depth_sort_scene`
- `material_state_scene`
- `offscreen_scene`
### 9.3 Editor Runtime Smoke
- SceneView / GameView 继续复用同一条 runtime frame composition
- object-id picking 不因 frame composition 改造回退
- editor overlay 不污染 runtime skybox / post-process
## 10. 风险与控制
### 风险 1为了接 skybox 强行把所有相机都改成离屏
后果:
- 复杂度和成本无意义上升
- 调试链路变长
控制策略:
- intermediate target 只按需启用
### 风险 2skybox 设计一开始就绑死 cubemap / IBL
后果:
- 阶段再次失焦
- 资源链路耦合过早
控制策略:
- 首版先做 builtin procedural skybox
### 风险 3post-process 入口继续走 editor 旧路径
后果:
- runtime / editor 边界重新混乱
控制策略:
- runtime post-process 必须是 renderer 正式阶段
- editor overlay 继续留在最后
## 11. 阶段完成判定
满足以下条件时,本阶段可视为收口:
1. renderer 具备正式 `Opaque -> Skybox -> Transparent -> PostProcess -> Final Output` 结构
2. skybox 有正式 runtime 数据入口与首版实现
3. post-process 有正式 fullscreen 入口与最小闭环
4. `skybox_scene``post_process_scene` 三后端通过
5. 现有 lighting / transparency / offscreen / camera stack 回归不破坏
## 12. 本阶段之后的正确下一步
当这一步收口后renderer 主线的下一阶段才应该考虑:
1. cubemap skybox / environment map
2. 曝光 / tone mapping / color grading 正式化
3. 更高阶的 renderer feature / C# SRP 承接层
而不是现在就跳去:
- `render graph`
- deferred
- editor-only 特效堆叠