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

4.1 KiB
Raw Blame History

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 2ScriptableRenderContext 增加显式 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 行为

的真正起点。