128 lines
4.1 KiB
Markdown
128 lines
4.1 KiB
Markdown
# SRP Managed Scene Draw API 计划 2026-04-20
|
||
|
||
## 1. 阶段目标
|
||
|
||
当前 SRP 主线已经完成:
|
||
1. `ScriptableRenderContext` 拥有 scene phase / injection 录制入口
|
||
2. Universal 默认 main-scene builtin passes 回到 `UniversalRenderer` 自己管理
|
||
3. managed fullscreen authoring 已经 builder 化
|
||
|
||
但现在的 main-scene draw 仍然是黑盒:
|
||
1. managed 侧只能 `RecordScenePhase(SceneRenderPhase.*)`
|
||
2. URP 包里的 `DrawObjectsPass` 还不是真正的 draw-objects authoring
|
||
3. 用户无法像 Unity SRP 一样控制 renderer list / filtering / sorting
|
||
|
||
这一阶段的目标是:
|
||
1. 把 native 已有的 scene draw primitives 正式抬到 managed API
|
||
2. 让 URP 包后续可以从“phase 黑盒”走向真正的 `DrawObjectsPass`
|
||
3. 为未来 C# 自定义渲染管线打下第一批 scene draw authoring 基元
|
||
|
||
## 2. 现状分析
|
||
|
||
### 2.1 native 侧已经有 draw 原语,但 managed 侧拿不到
|
||
|
||
当前 native 已存在:
|
||
1. `RendererListType`
|
||
2. `FilteringSettings`
|
||
3. `SortingSettings`
|
||
4. `RendererListDesc`
|
||
5. `DrawSettings`
|
||
|
||
而 builtin forward 也已经按这些原语工作:
|
||
1. opaque -> `RendererListType::Opaque`
|
||
2. transparent -> `RendererListType::Transparent`
|
||
3. 最终由 `VisitRendererListVisibleItems(...)` 完成可见物体遍历
|
||
|
||
所以问题不是底层没有能力,而是:
|
||
1. 这些能力仍被 builtin forward 内部私有化
|
||
2. managed SRP/URP 还只能调用 phase 黑盒
|
||
|
||
### 2.2 当前 `SceneRenderPhase` 只能做“整段默认绘制”
|
||
|
||
这对于现阶段收口很有价值,但它的上限明显不够:
|
||
1. 无法表达只绘制 opaque / transparent 的一个子集
|
||
2. 无法表达自定义 filtering / sorting
|
||
3. 无法自然演进到 Unity 风格 `DrawObjectsPass`
|
||
|
||
## 3. 本阶段范围
|
||
|
||
本阶段优先做:
|
||
1. 梳理 native scene draw 原语与 builtin forward 的耦合点
|
||
2. 确定第一批暴露到 managed 的最小 API 集
|
||
3. 先打通最小可用 scene draw 调用链
|
||
4. 用它替换 Universal 默认对象绘制 pass 的黑盒 phase 依赖
|
||
5. `XCEditor` 重编译与旧 editor 冒烟
|
||
|
||
本阶段暂不做:
|
||
1. 全量照搬 Unity 所有 drawing/filtering 状态
|
||
2. layer mask / render queue range / shader tag id 的完整体系
|
||
3. renderer list 缓存优化
|
||
4. deferred renderer
|
||
|
||
## 4. 建议切口
|
||
|
||
### Step 1:先暴露最小可用 scene draw 描述
|
||
|
||
建议先暴露:
|
||
1. `RendererListType`
|
||
2. `RendererSortMode`
|
||
3. `FilteringSettings`
|
||
4. `SortingSettings`
|
||
5. `RendererListDesc`
|
||
|
||
原因:
|
||
1. 这些类型 native 已经存在
|
||
2. 数据结构简单,不需要先把整套 Unity 复杂状态一次性搬完
|
||
3. 足够支撑第一个 managed `DrawObjectsPass`
|
||
|
||
### Step 2:在 `ScriptableRenderContext` 增加显式 scene draw 入口
|
||
|
||
不要继续扩展 `RecordScenePhase(...)` 黑盒。
|
||
建议新增类似:
|
||
1. `CreateRendererList(...)`
|
||
2. `DrawRendererList(...)`
|
||
|
||
或者第一阶段更务实一点:
|
||
1. `DrawRenderers(RendererListDesc desc, SceneRenderPhase phase)`
|
||
|
||
原则:
|
||
1. API 命名要朝 Unity 靠拢
|
||
2. 但实现可以先走引擎现有 `RendererListType` 体系
|
||
|
||
### Step 3:让 Universal 默认对象 pass 开始消费新 API
|
||
|
||
目标不是一次性推翻全部逻辑,而是先替换:
|
||
1. `UniversalDrawObjectsPass(opaque)`
|
||
2. `UniversalDrawObjectsPass(transparent)`
|
||
|
||
让它们不再直接 `context.RecordScenePhase(...)`
|
||
而是基于新的 scene draw API 录制对象绘制。
|
||
|
||
Skybox 可以后续单独处理,因为它不是 renderer list 驱动的对象遍历。
|
||
|
||
## 5. 验收标准
|
||
|
||
这一阶段收口后应满足:
|
||
1. managed 侧首次拥有正式的 scene draw primitives
|
||
2. Universal 的对象绘制 pass 不再完全依赖 phase 黑盒
|
||
3. 后续继续实现真正 Unity 风格 `DrawObjectsPass` 时,不需要再推翻这一层
|
||
4. `XCEditor` 编译通过
|
||
5. 旧 editor 冒烟通过
|
||
|
||
## 6. 阶段意义
|
||
|
||
这一步完成后,SRP 主线会从:
|
||
|
||
`managed 可以组织主场景顺序,但对象绘制仍是 native 黑盒`
|
||
|
||
推进到:
|
||
|
||
`managed 开始拥有可组合的 scene draw primitives`
|
||
|
||
这才是后面继续做:
|
||
1. Unity 风格 `DrawObjectsPass`
|
||
2. renderer feature 自定义对象绘制
|
||
3. 更细的 filtering / sorting / override 行为
|
||
|
||
的真正起点。
|