153 lines
6.7 KiB
Markdown
153 lines
6.7 KiB
Markdown
|
|
# Scene View Render Plan And Failure Flow
|
|||
|
|
|
|||
|
|
## 先建立正确心智模型
|
|||
|
|
|
|||
|
|
当前 Scene View 不是“把活动场景直接交给 `SceneRenderer`”这么简单。
|
|||
|
|
|
|||
|
|
它真实的工作方式更接近商业引擎编辑器常见的两层结构:
|
|||
|
|
|
|||
|
|
1. 运行时渲染层
|
|||
|
|
- 负责把场景和相机变成基础 `CameraRenderRequest`
|
|||
|
|
2. 编辑器附加层
|
|||
|
|
- 负责网格、selection outline、editor overlay、object-id 与状态文案
|
|||
|
|
|
|||
|
|
`SceneViewportRenderPlan` 正是第二层里的一个关键中间件,而当前 `ViewportHostService` 与它之间还多了一层 [SceneViewportRenderPassBundle](../../XCEngine/Editor/Viewport/SceneViewportRenderPassBundle/SceneViewportRenderPassBundle.md),专门负责持有 grid / outline / overlay renderer 并提供 factory。
|
|||
|
|
|
|||
|
|
## 当前主调用链
|
|||
|
|
|
|||
|
|
按 `ViewportHostService.h` 当前实现,Scene View 一帧渲染大致是:
|
|||
|
|
|
|||
|
|
1. `RenderRequestedViewports(...)` 遍历本帧请求过的视口。
|
|||
|
|
2. `RenderViewportEntry(...)` 检查 `colorView` / `depthView` 是否存在。
|
|||
|
|
3. 如果是 Scene 视口,进入 `RenderSceneViewportEntry(...)`。
|
|||
|
|
4. 检查隐藏编辑器 Scene View 相机是否可用。
|
|||
|
|
5. 检查活动场景是否存在。
|
|||
|
|
6. `BuildSceneViewportRenderState(...)`:
|
|||
|
|
- 读取 `SceneViewportOverlayData`
|
|||
|
|
- 读取当前选中对象列表
|
|||
|
|
- 读取 `SceneViewportOverlayFrameData`
|
|||
|
|
- 调用 `m_sceneViewportRenderPassBundle.BuildRenderPlan(...)`
|
|||
|
|
- bundle 内部再调用 `BuildSceneViewportRenderPlan(...)`
|
|||
|
|
7. `SceneRenderer::BuildRenderRequests(...)` 生成基础 request。
|
|||
|
|
8. `ApplySceneViewportRenderPlan(...)` 把 editor 附加项写回 request。
|
|||
|
|
9. `SceneRenderer::Render(requests)` 执行真正的场景渲染。
|
|||
|
|
10. `MarkSceneViewportRenderSuccess(...)` 回写颜色状态、object-id 状态和有效标记。
|
|||
|
|
|
|||
|
|
## `SceneViewportRenderPlan` 到底负责什么
|
|||
|
|
|
|||
|
|
它当前只负责三类附加项:
|
|||
|
|
|
|||
|
|
- `postScenePasses`
|
|||
|
|
- 无限网格
|
|||
|
|
- selection outline
|
|||
|
|
- `overlayPasses`
|
|||
|
|
- editor overlay
|
|||
|
|
- clear-color override
|
|||
|
|
- 默认 Scene View 背景色是 `(0.27, 0.27, 0.27, 1.0)`
|
|||
|
|
|
|||
|
|
这意味着它不是 Scene View 的全部流程,只是“把 Scene View 专属附加能力组织成一个可应用的 plan”。
|
|||
|
|
|
|||
|
|
## 为什么要有默认 clear-color override
|
|||
|
|
|
|||
|
|
因为 Scene View 的定位不是游戏运行结果,而是编辑工作台。
|
|||
|
|
|
|||
|
|
如果完全复用场景相机自己的 clear 语义,编辑体验会出现两个问题:
|
|||
|
|
|
|||
|
|
- 背景风格可能随场景内容波动,不稳定
|
|||
|
|
- 编辑器 overlay、gizmo、网格失去统一视觉基底
|
|||
|
|
|
|||
|
|
当前默认灰色背景,是典型的编辑器视图设计:优先保证工作环境一致性,再叠加运行时内容。
|
|||
|
|
|
|||
|
|
## 为什么 warning 不直接终止渲染
|
|||
|
|
|
|||
|
|
一个很典型的例子是:
|
|||
|
|
|
|||
|
|
- 选中了对象
|
|||
|
|
- 需要 selection outline
|
|||
|
|
- 但 `objectIdShaderView` 不可用
|
|||
|
|
|
|||
|
|
这时当前实现不会直接让 Scene View 失败,而是:
|
|||
|
|
|
|||
|
|
- 返回 warning `Scene object id shader view is unavailable`
|
|||
|
|
- 继续保留网格、主场景和 overlay 的正常渲染
|
|||
|
|
|
|||
|
|
这是编辑器设计里非常关键的原则:**局部能力缺口优先降级,而不是整页黑屏**。
|
|||
|
|
|
|||
|
|
## 失败回退是怎么接进来的
|
|||
|
|
|
|||
|
|
Scene View 的失败回退不在 `SceneViewportRenderPlan` 自己内部处理,而是交给:
|
|||
|
|
|
|||
|
|
- [ViewportHostRenderFlowUtils](../../XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ViewportHostRenderFlowUtils.md)
|
|||
|
|
|
|||
|
|
其中最关键的策略包括:
|
|||
|
|
|
|||
|
|
- `BuildSceneViewportRenderFailurePolicy(...)`
|
|||
|
|
- `ApplyViewportFailureStatus(...)`
|
|||
|
|
- `InvalidateViewportObjectIdFrame(...)`
|
|||
|
|
- `MarkSceneViewportRenderSuccess(...)`
|
|||
|
|
|
|||
|
|
也就是说:
|
|||
|
|
|
|||
|
|
- render plan 负责“本帧附加画什么”
|
|||
|
|
- flow utils 负责“失败时怎么退、成功后怎么收尾”
|
|||
|
|
|
|||
|
|
这样的分工会让 Scene View 主链更稳。
|
|||
|
|
|
|||
|
|
## 为什么要把 Build 和 Apply 分开
|
|||
|
|
|
|||
|
|
如果把 plan 构建和 request 写回混成一个函数,短期看代码会少一些,但长期会带来三个问题:
|
|||
|
|
|
|||
|
|
1. 很难单独测试规划逻辑
|
|||
|
|
2. 很容易在复用 `CameraRenderRequest` 时留下脏指针
|
|||
|
|
3. `ViewportHostService` 会重新变成一大段条件拼装代码
|
|||
|
|
|
|||
|
|
当前拆成:
|
|||
|
|
|
|||
|
|
- `BuildSceneViewportRenderPlan(...)`
|
|||
|
|
- `ApplySceneViewportRenderPlan(...)`
|
|||
|
|
|
|||
|
|
本质上是在把“决策”和“接线”分离。这种拆法在商业引擎里很常见,因为它更容易维护,也更适合持续往 Scene View 里加新能力。
|
|||
|
|
|
|||
|
|
## Game View 为什么不用这套 plan
|
|||
|
|
|
|||
|
|
Game View 的目标是尽量忠实呈现运行时相机结果,所以它没有:
|
|||
|
|
|
|||
|
|
- editor 私有背景
|
|||
|
|
- 网格
|
|||
|
|
- selection outline
|
|||
|
|
- gizmo overlay
|
|||
|
|
|
|||
|
|
因此它直接走 `SceneRenderer`,成功后只做最基本的颜色状态回写与 object-id 失效处理。
|
|||
|
|
|
|||
|
|
## 当前最重要的设计收益
|
|||
|
|
|
|||
|
|
现在这套链路真正带来的收益不是“代码更优雅”,而是三个更现实的好处:
|
|||
|
|
|
|||
|
|
- Scene View 可以在局部能力缺失时尽量继续工作
|
|||
|
|
- 编辑器附加渲染和运行时场景渲染保持分层
|
|||
|
|
- 每一层都可以被单独测试和文档化
|
|||
|
|
|
|||
|
|
这正是商业级编辑器最需要的特征:稳定、可诊断、可扩展。
|
|||
|
|
|
|||
|
|
## 建议阅读顺序
|
|||
|
|
|
|||
|
|
1. [ViewportHostService](../../XCEngine/Editor/Viewport/ViewportHostService/ViewportHostService.md)
|
|||
|
|
2. [ViewportHostService::RenderRequestedViewports](../../XCEngine/Editor/Viewport/ViewportHostService/RenderRequestedViewports.md)
|
|||
|
|
3. [SceneViewportRenderPassBundle](../../XCEngine/Editor/Viewport/SceneViewportRenderPassBundle/SceneViewportRenderPassBundle.md)
|
|||
|
|
4. [SceneViewportRenderPlan](../../XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportRenderPlan.md)
|
|||
|
|
5. [BuildSceneViewportRenderPlan](../../XCEngine/Editor/Viewport/SceneViewportRenderPlan/BuildSceneViewportRenderPlan.md)
|
|||
|
|
6. [ApplySceneViewportRenderPlan](../../XCEngine/Editor/Viewport/SceneViewportRenderPlan/ApplySceneViewportRenderPlan.md)
|
|||
|
|
7. [ViewportHostRenderFlowUtils](../../XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ViewportHostRenderFlowUtils.md)
|
|||
|
|
8. [ApplySceneViewportRenderRequestSetup](../../XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ApplySceneViewportRenderRequestSetup.md)
|
|||
|
|
9. [MarkSceneViewportRenderSuccess](../../XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/MarkSceneViewportRenderSuccess.md)
|
|||
|
|
|
|||
|
|
## 相关文档
|
|||
|
|
|
|||
|
|
- [Editor Architecture And Workflow](Editor-Architecture-And-Workflow.md)
|
|||
|
|
- [SceneView Interaction And Gizmo Model](SceneView-Interaction-And-Gizmo-Model.md)
|
|||
|
|
- [Viewport](../../XCEngine/Editor/Viewport/Viewport.md)
|
|||
|
|
- [ViewportHostService](../../XCEngine/Editor/Viewport/ViewportHostService/ViewportHostService.md)
|
|||
|
|
- [SceneViewportRenderPassBundle](../../XCEngine/Editor/Viewport/SceneViewportRenderPassBundle/SceneViewportRenderPassBundle.md)
|
|||
|
|
- [SceneViewportRenderPlan](../../XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportRenderPlan.md)
|
|||
|
|
- [ViewportHostRenderFlowUtils](../../XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ViewportHostRenderFlowUtils.md)
|