# 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)