Files
XCEngine/docs/plan/SRP_ManagedSceneDrawAPI计划_2026-04-20.md

128 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 行为
的真正起点。