docs: expand scene viewport chrome and render plan docs

This commit is contained in:
2026-04-04 16:57:37 +08:00
parent b9cde699cc
commit ccbbb481f4
16 changed files with 438 additions and 125 deletions

View File

@@ -0,0 +1,43 @@
# BuildSceneViewportToolCommand
**命名空间**: `XCEngine::Editor`
**类型**: `function`
**源文件**: `editor/src/Viewport/SceneViewportChrome.h`
## 签名
```cpp
SceneViewportToolCommand BuildSceneViewportToolCommand(
const SceneViewportToolOverlayResult& overlayResult,
const SceneViewportToolShortcutAction& shortcutAction);
```
## 作用
把工具按钮点击和键盘快捷键动作折叠成统一的 Scene View 工具命令。
## 当前实现行为
- 如果 `overlayResult.clicked == true`
- 先把 `targetTool` 设为 `overlayResult.clickedTool`
-`triggered = true`
- 并默认要求取消 move / rotate / scale 三类 gizmo 拖拽
- 如果 `shortcutAction.HasAction() == true`
- 用快捷键目标覆盖 `targetTool`
- 保持 `triggered = true`
- 把三个 `cancel*Gizmo` 标志按逻辑或合并,而不是覆盖
`tests/Editor/test_scene_viewport_chrome.cpp` 当前验证了:
- overlay 点击可以独立形成完整工具切换命令
- 快捷键可以在 overlay 未触发时生成命令
- 当两者同时触发时,快捷键会覆盖目标工具,但保留 cancel 标志并集
## 相关文档
- [SceneViewportChrome](SceneViewportChrome.md)
- [SceneViewportToolOverlayResult](SceneViewportToolOverlayResult.md)
- [SceneViewportToolCommand](SceneViewportToolCommand.md)
- [SceneViewportToolShortcutAction](../SceneViewportNavigation/SceneViewportToolShortcutAction.md)

View File

@@ -0,0 +1,43 @@
# ExecuteSceneViewportToolCommand
**命名空间**: `XCEngine::Editor`
**类型**: `function`
**源文件**: `editor/src/Viewport/SceneViewportChrome.h`
## 签名
```cpp
void ExecuteSceneViewportToolCommand(
const SceneViewportToolCommand& command,
IUndoManager& undoManager,
SceneViewportMoveGizmo& moveGizmo,
SceneViewportRotateGizmo& rotateGizmo,
SceneViewportScaleGizmo& scaleGizmo,
SceneViewportToolMode& toolMode);
```
## 作用
执行工具切换命令,并在切换前按需安全结束当前 gizmo 交互拖拽。
## 当前实现行为
1. 如果 `command.HasAction() == false`,直接 `no-op`
2. 根据 `cancelMoveGizmo / cancelRotateGizmo / cancelScaleGizmo`
- 只在对应 gizmo 当前 `IsActive()` 时才调用 `CancelDrag(&undoManager)`
3. 最后把 `toolMode` 改成 `command.targetTool`
这意味着它既负责“切工具”,也负责在切工具前安全收口当前交互式拖拽。
## 当前边界
- 不生成命令,只执行命令。
- 不直接刷新 gizmo frame也不提交 overlay state。
## 相关文档
- [SceneViewportChrome](SceneViewportChrome.md)
- [SceneViewportToolCommand](SceneViewportToolCommand.md)
- [BuildSceneViewportToolCommand](BuildSceneViewportToolCommand.md)

View File

@@ -0,0 +1,46 @@
# RenderSceneViewportToolOverlay
**命名空间**: `XCEngine::Editor`
**类型**: `function`
**源文件**: `editor/src/Viewport/SceneViewportChrome.h`
## 签名
```cpp
SceneViewportToolOverlayResult RenderSceneViewportToolOverlay(
const ViewportPanelContentResult& content,
SceneViewportToolMode activeTool);
```
## 作用
在 Scene View 内容区左上角绘制工具按钮 overlay并返回即时 UI 结果。
## 当前实现行为
-`content.hasViewportArea == false` 时,直接返回空结果。
- 当前固定绘制 5 个工具按钮:
- `ViewMove`
- `Move`
- `Rotate`
- `Scale`
- `Transform`
- 图标路径当前按 `resources/Icons/<tool>[_on].png` 规则拼接,并带静态缓存。
- 如果图标预览加载失败,会退回文本绘制。
- 只返回 `hovered / clicked / clickedTool`,不直接修改 `toolMode`
## 返回值
返回 [SceneViewportToolOverlayResult](SceneViewportToolOverlayResult.md)
- `hovered` 表示鼠标是否位于任一工具按钮上
- `clicked` 表示当前帧是否点击了某个工具按钮
- `clickedTool` 表示点击命中的目标工具
## 相关文档
- [SceneViewportChrome](SceneViewportChrome.md)
- [SceneViewportToolOverlayResult](SceneViewportToolOverlayResult.md)
- [SceneViewportToolMode](../SceneViewportEditorModes/SceneViewportToolMode.md)

View File

@@ -0,0 +1,39 @@
# RenderSceneViewportTopBar
**命名空间**: `XCEngine::Editor`
**类型**: `function`
**源文件**: `editor/src/Viewport/SceneViewportChrome.h`
## 签名
```cpp
void RenderSceneViewportTopBar(
SceneViewportPivotMode& pivotMode,
SceneViewportTransformSpaceMode& transformSpaceMode);
```
## 作用
绘制 Scene View 顶部 toolbar并直接切换 `Pivot / Center``Global / Local` 两组模式。
## 当前实现行为
- 使用 `UI::PanelToolbarScope` 打开名为 `SceneToolbar` 的 toolbar 区域。
- 如果 toolbar 没有打开,函数直接返回。
- 当前只绘制两枚 toggle button
- `Pivot` / `Center`
- `Global` / `Local`
- 每次点击都会在对应的两种模式之间直接翻转,不经过额外命令层。
## 当前边界
- 只改写 `pivotMode``transformSpaceMode`,不处理 `toolMode`
- 不负责命中解析、gizmo 刷新或导航状态。
## 相关文档
- [SceneViewportChrome](SceneViewportChrome.md)
- [SceneViewportPivotMode](../SceneViewportEditorModes/SceneViewportPivotMode.md)
- [SceneViewportTransformSpaceMode](../SceneViewportEditorModes/SceneViewportTransformSpaceMode.md)

View File

@@ -8,128 +8,60 @@
**描述**: 收口 Scene View 顶部 toolbar、左侧工具按钮 overlay以及工具切换命令折叠与执行逻辑的 Viewport UI helper。
## 概
## 概
`SceneViewportChrome` 解决的是 `SceneViewPanel` 里最靠近 UI chrome 的那一层问题:
- 顶部 toolbar 如何切换 `Pivot / Center` `Global / Local`
- 左侧工具按钮 overlay 如何反馈 hovered / clicked
- 顶部 toolbar 如何切换 `Pivot / Center` `Global / Local`
- 左侧工具按钮 overlay 如何返回 hovered / clicked
- 工具按钮点击与键盘快捷键如何折叠成统一命令
- 切换工具前哪些 gizmo 需要先取消交互式拖拽
它本身不处理命中解析、导航输入、overlay frame 或 gizmo 生命周期命令;这些职责分别留在
[SceneViewportInteractionFrame](../SceneViewportInteractionFrame/SceneViewportInteractionFrame.md)、
[SceneViewportNavigation](../SceneViewportNavigation/SceneViewportNavigation.md) 和
[SceneViewportTransformGizmoCoordinator](../SceneViewportTransformGizmoCoordinator/SceneViewportTransformGizmoCoordinator.md)。
它本身不处理命中解析、导航输入、overlay frame 或 gizmo 生命周期命令;这些职责分别留在 [SceneViewportInteractionFrame](../SceneViewportInteractionFrame/SceneViewportInteractionFrame.md)、[SceneViewportNavigation](../SceneViewportNavigation/SceneViewportNavigation.md) 和 [SceneViewportTransformGizmoCoordinator](../SceneViewportTransformGizmoCoordinator/SceneViewportTransformGizmoCoordinator.md)。
## 公开类型与函数
### `SceneViewportToolOverlayResult`
| 成员 | 说明 |
|------|------|
| [SceneViewportToolOverlayResult](SceneViewportToolOverlayResult.md) | 左侧工具按钮 overlay 的即时 UI 结果。 |
| [SceneViewportToolCommand](SceneViewportToolCommand.md) | 把点击与快捷键折叠后的统一工具命令。 |
| [RenderSceneViewportTopBar](RenderSceneViewportTopBar.md) | 绘制并切换顶部 `Pivot / Center``Global / Local` toolbar。 |
| [RenderSceneViewportToolOverlay](RenderSceneViewportToolOverlay.md) | 绘制视口左上角工具按钮 overlay。 |
| [BuildSceneViewportToolCommand](BuildSceneViewportToolCommand.md) | 把 overlay 点击与快捷键动作折叠成统一工具命令。 |
| [ExecuteSceneViewportToolCommand](ExecuteSceneViewportToolCommand.md) | 真正执行工具切换,并按需取消现有 gizmo 拖拽。 |
记录左侧工具按钮 overlay 的即时 UI 结果:
## 调用链
- `hovered`
- 鼠标当前是否落在任意工具按钮上
- `clicked`
- 本帧是否发生按钮点击
- `clickedTool`
- 若发生点击,对应被选中的目标工具
`editor/src/panels/SceneViewPanel.cpp` 的当前实现Scene View 每帧会按下面顺序消费这份 header
`SceneViewPanel` 当前用它把“鼠标是否停在工具按钮上”从视口内容 hovered 状态里扣掉,避免点击工具按钮时误走 Scene View 内容交互。
### `SceneViewportToolCommand`
把工具按钮点击与键盘快捷键统一成一份可执行命令:
- `targetTool`
- `triggered`
- `cancelMoveGizmo`
- `cancelRotateGizmo`
- `cancelScaleGizmo`
`HasAction()` 当前只是返回 `triggered`,不附带额外 guard。
### `RenderSceneViewportTopBar(...)`
绘制顶部 toolbar并直接更新
- `SceneViewportPivotMode`
- `SceneViewportTransformSpaceMode`
当前实现使用两枚 toggle button
- `Pivot` / `Center`
- `Global` / `Local`
每次点击都会在两种模式之间直接翻转,不经过额外命令层。
### `RenderSceneViewportToolOverlay(...)`
在视口内容左上角绘制 5 个工具按钮:
- `ViewMove`
- `Move`
- `Rotate`
- `Scale`
- `Transform`
当前实现行为是:
- `content.hasViewportArea == false` 时直接返回空结果
- 优先按当前可执行文件目录推导 `resources/Icons/<tool>[_on].png`
- 如果图标贴图预览失败,则退回文字 tooltip / 文本绘制
- 只返回即时 UI 结果,不直接修改 `toolMode`
### `BuildSceneViewportToolCommand(...)`
把两路输入折叠成统一工具命令:
- 鼠标点击 overlay 按钮
- [SceneViewportNavigation](../SceneViewportNavigation/SceneViewportNavigation.md) 产出的快捷键动作
当前规则是:
- overlay 点击一旦命中,默认会要求取消全部 gizmo 拖拽
- 若快捷键动作也触发,会覆盖 `targetTool`
- 三个 `cancel*` 标志按逻辑或合并,而不是互相覆盖
### `ExecuteSceneViewportToolCommand(...)`
真正执行工具切换命令。
当前实现会:
1.`HasAction() == false`,直接 no-op
2.`move / rotate / scale` gizmo 分别按 `cancel*` 标志决定是否调用 `CancelDrag(&undoManager)`
3. 最后把 `toolMode` 改成 `targetTool`
这意味着它既负责“切工具”,也负责在切工具前安全结束当前交互式拖拽。
## 当前调用链
`SceneViewPanel.cpp` 的当前实现Scene View 每帧会按下面的顺序消费这份 header
1. 先调用 `RenderSceneViewportTopBar(...)`
2. 再调用 `RenderSceneViewportToolOverlay(...)`
3.`BuildSceneViewportToolShortcutAction(...)` 生成快捷键动作
4. 再用 `BuildSceneViewportToolCommand(...)` 合并 UI 点击和快捷键
5. 最后用 `ExecuteSceneViewportToolCommand(...)` 更新 `m_toolMode`
1. 先调用 [RenderSceneViewportTopBar](RenderSceneViewportTopBar.md)
2. 再调用 [RenderSceneViewportToolOverlay](RenderSceneViewportToolOverlay.md)
3. 用 [BuildSceneViewportToolShortcutAction](../SceneViewportNavigation/BuildSceneViewportToolShortcutAction.md) 生成快捷键动作
4. 再用 [BuildSceneViewportToolCommand](BuildSceneViewportToolCommand.md) 合并 UI 点击和快捷键
5. 最后用 [ExecuteSceneViewportToolCommand](ExecuteSceneViewportToolCommand.md) 更新 `m_toolMode`
也就是说,这一层是 `SceneViewPanel` 进入 `tool state / interaction frame / navigation state` 之前的最前置 UI chrome 装配层。
## 测试锚点
`tests/Editor/test_scene_viewport_chrome.cpp` 当前覆盖了:
- overlay 点击触发的完整工具切换命令
- 快捷键动作在 overlay 未触发时的工具命令映射
- 快捷键覆盖 overlay 目标工具、但保留 cancel 标志并集
- 执行工具命令时对 `toolMode` 的更新
## 当前边界
- 只服务于 Scene View UI chrome不参与 Game View。
- 它不负责判断“当前是否允许解析 Scene View 内容交互”;这部分在 [CanResolveSceneViewportInteraction](../SceneViewportNavigation/SceneViewportNavigation.md)
- 它不直接刷新 gizmo frame也不提交 overlay state这部分在 [SceneViewportInteractionFrame](../SceneViewportInteractionFrame/SceneViewportInteractionFrame.md) 与 [SceneViewportTransformGizmoCoordinator](../SceneViewportTransformGizmoCoordinator/SceneViewportTransformGizmoCoordinator.md)
- 当前已有独立单元测试 `tests/Editor/test_scene_viewport_chrome.cpp`,覆盖工具命令折叠与执行规则。
- 顶部 toolbar / 左侧按钮 overlay 的绘制细节仍主要由 `editor/src/Viewport/SceneViewportChrome.cpp``editor/src/panels/SceneViewPanel.cpp` 共同锚定。
- 只服务于 Scene View UI chrome不参与 Game View。
- 绘制细节主要锚定在 `editor/src/Viewport/SceneViewportChrome.cpp``SceneViewPanel.cpp` 当前只负责按帧编排调用
- `RenderSceneViewportToolOverlay(...)` 只返回即时 UI 结果,不直接改写 `toolMode`
## 相关文档
- [Viewport](../Viewport.md)
- [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md)
- [SceneViewportEditorModes](../SceneViewportEditorModes/SceneViewportEditorModes.md)
- [SceneViewportInteractionFrame](../SceneViewportInteractionFrame/SceneViewportInteractionFrame.md)
- [SceneViewportNavigation](../SceneViewportNavigation/SceneViewportNavigation.md)
- [SceneViewportInteractionFrame](../SceneViewportInteractionFrame/SceneViewportInteractionFrame.md)
- [SceneViewportTransformGizmoCoordinator](../SceneViewportTransformGizmoCoordinator/SceneViewportTransformGizmoCoordinator.md)

View File

@@ -0,0 +1,28 @@
# SceneViewportToolCommand
**命名空间**: `XCEngine::Editor`
**类型**: `struct`
**源文件**: `editor/src/Viewport/SceneViewportChrome.h`
## 字段
| 字段 | 类型 | 说明 |
|------|------|------|
| `targetTool` | `SceneViewportToolMode` | 最终要切换到的工具。默认值是 `Move`。 |
| `triggered` | `bool` | 当前帧是否真的形成工具切换命令。 |
| `cancelMoveGizmo` | `bool` | 执行前是否需要取消 move gizmo 拖拽。 |
| `cancelRotateGizmo` | `bool` | 执行前是否需要取消 rotate gizmo 拖拽。 |
| `cancelScaleGizmo` | `bool` | 执行前是否需要取消 scale gizmo 拖拽。 |
## 当前语义
- `HasAction()` 当前只返回 `triggered`
- 这是轻量命令对象,真正的取消拖拽与工具切换由 [ExecuteSceneViewportToolCommand](ExecuteSceneViewportToolCommand.md) 完成。
## 相关文档
- [SceneViewportChrome](SceneViewportChrome.md)
- [BuildSceneViewportToolCommand](BuildSceneViewportToolCommand.md)
- [ExecuteSceneViewportToolCommand](ExecuteSceneViewportToolCommand.md)

View File

@@ -0,0 +1,26 @@
# SceneViewportToolOverlayResult
**命名空间**: `XCEngine::Editor`
**类型**: `struct`
**源文件**: `editor/src/Viewport/SceneViewportChrome.h`
## 字段
| 字段 | 类型 | 说明 |
|------|------|------|
| `hovered` | `bool` | 鼠标当前是否落在任意工具按钮上。 |
| `clicked` | `bool` | 本帧是否发生工具按钮点击。 |
| `clickedTool` | `SceneViewportToolMode` | 若发生点击,对应被选中的目标工具。默认值是 `Move`。 |
## 当前语义
- `SceneViewPanel::Render()` 当前会把 `toolOverlay.hovered` 从 viewport 内容悬停判定里扣掉,避免点工具按钮时误走 Scene View 内容交互。
- `clickedTool` 只在 `clicked == true` 时有实际语义。
## 相关文档
- [SceneViewportChrome](SceneViewportChrome.md)
- [RenderSceneViewportToolOverlay](RenderSceneViewportToolOverlay.md)
- [BuildSceneViewportToolCommand](BuildSceneViewportToolCommand.md)

View File

@@ -17,7 +17,7 @@ void ApplySceneViewportRenderPlan(
## 作用
把已经构建好的 `SceneViewportRenderPlan` 写入目标 `CameraRenderRequest`
把已经构建好的 [SceneViewportRenderPlan](SceneViewportRenderPlan.md) 写入目标 `CameraRenderRequest`,使本帧 Scene View request 具备 editor 专属附加行为
## 当前实现行为
@@ -35,19 +35,56 @@ ApplySceneViewportRenderRequestSetup(
1. 如果 `plan.HasOverlayPasses()` 为真,把 `request.overlayPasses` 指向 `plan.overlayPasses`
2. 无条件把 `plan.hasClearColorOverride``plan.clearColorOverride` 复制到 request
## 与 `ApplySceneViewportRenderRequestSetup(...)` 的分工
[ApplySceneViewportRenderRequestSetup](../ViewportHostRenderFlowUtils/ApplySceneViewportRenderRequestSetup.md) 负责的是 Scene View request 的基础接线:
- 清理旧的 `preScenePasses` / `postScenePasses` / `overlayPasses`
- 清理旧的 object-id 设置
- 按条件接入 `postScenePasses`
- 按条件接入 object-id surface
而本函数只在这之后补两件 Scene View render plan 语义:
- overlay pass
- clear-color override
因此这两个函数不是重复关系,而是“基础 request 装配”与“render plan 应用”的上下层关系。
## 当前语义边界
- object-id surface 和 `postScenePasses` 的挂接规则,仍由 `ApplySceneViewportRenderRequestSetup(...)` 定义
- 该函数不负责生成 `request.surface`,也不负责构建 plan只负责“把 plan 应用到 request”
- `overlayPasses` 只有在非空时才会挂到 request空序列不会暴露出去
- 它不负责构建 `request.surface`
- 它不负责决定本帧 plan 里应该有哪些 pass
- 它不会强行把空的 overlay 序列挂到 request 上
- 它会始终把 clear-color override 从 plan 写回 request即使本帧没有额外 pass。
最后一点非常关键,因为 Scene View 默认背景色本来就是 plan 语义的一部分,而不依赖当前有没有 grid / overlay。
## 测试锚点
- `ApplySceneViewportRenderPlanAttachesPlannedPassesAndClearState`
`ApplySceneViewportRenderPlanAttachesPlannedPassesAndClearState` 验证了:
- `request.postScenePasses` 会指向 `plan.postScenePasses`
- `request.overlayPasses` 会在非空时接入
- object-id surface 会被请求
- clear-color override 会被正确写回
## 设计说明
把“把 plan 应用到 request”单独收口是为了保证 `ViewportHostService` 最核心的 Scene View 执行路径足够稳定:
1. 先拿到运行时 `CameraRenderRequest`
2. 再在 Editor 层补 plan
3. 最后统一交给 `SceneRenderer`
这比在 service 里零散地改 request 各字段更可靠,因为所有 Scene View 附加语义都通过同一个入口回写,减少了遗漏和跨帧残留指针的风险。
## 相关文档
- [SceneViewportRenderPlan](SceneViewportRenderPlan.md)
- [HasOverlayPasses](HasOverlayPasses.md)
- [BuildSceneViewportRenderPlan](BuildSceneViewportRenderPlan.md)
- [HasOverlayPasses](HasOverlayPasses.md)
- [ApplySceneViewportRenderRequestSetup](../ViewportHostRenderFlowUtils/ApplySceneViewportRenderRequestSetup.md)
- [ViewportHostRenderFlowUtils](../ViewportHostRenderFlowUtils/ViewportHostRenderFlowUtils.md)
- [CameraRenderRequest](../../../Rendering/CameraRenderRequest/CameraRenderRequest.md)
- [Scene View Render Plan And Failure Flow](../../../../_guides/Editor/Scene-Viewport-Render-Plan-And-Failure-Flow.md)

View File

@@ -18,7 +18,7 @@ bool HasOverlayPasses() const;
## 当前实现行为
当前只是返回:
当前实现只是返回:
```cpp
overlayPasses.GetPassCount() > 0
@@ -26,8 +26,28 @@ overlayPasses.GetPassCount() > 0
这也是 [ApplySceneViewportRenderPlan](ApplySceneViewportRenderPlan.md) 决定是否把 `request.overlayPasses` 指向 `plan.overlayPasses` 的直接依据。
## 当前语义
这里的 overlay pass 当前主要指 editor overlay
- 相机与灯光辅助图标
- transform gizmo 图元
- 其他由 `SceneViewportOverlayFrameData` 驱动的屏幕叠加几何
## 设计说明
overlay pass 是 Scene View 比运行时视图更“编辑器化”的一层。
把它和 post-scene pass 分开判断,可以让调用方更明确地区分:
- 这是场景空间增强
- 还是最终叠加层
这对后续继续扩展 Scene View pass 类型会很重要。
## 相关文档
- [SceneViewportRenderPlan](SceneViewportRenderPlan.md)
- [HasPostScenePasses](HasPostScenePasses.md)
- [ApplySceneViewportRenderPlan](ApplySceneViewportRenderPlan.md)
- [SceneViewportOverlayPassFactory](SceneViewportOverlayPassFactory.md)

View File

@@ -18,7 +18,7 @@ bool HasPostScenePasses() const;
## 当前实现行为
当前只是返回:
当前实现只是返回:
```cpp
postScenePasses.GetPassCount() > 0
@@ -26,8 +26,22 @@ postScenePasses.GetPassCount() > 0
因此空的 `RenderPassSequence` 不会被视为“已配置 post-scene pass”。
## 当前语义
这里的 post-scene pass 当前主要包括:
- Scene View 无限网格
- selection outline
它们都属于“在主场景之后追加,但仍然围绕场景空间语义工作”的 pass。
## 设计说明
把这个判断留在 plan 上,而不是散落到各个调用点,有助于维持 API 语义统一:调用方不需要自己看 pass count只需要问“这个 plan 有没有 post-scene pass”。
## 相关文档
- [SceneViewportRenderPlan](SceneViewportRenderPlan.md)
- [HasOverlayPasses](HasOverlayPasses.md)
- [ApplySceneViewportRenderRequestSetup](../ViewportHostRenderFlowUtils/ApplySceneViewportRenderRequestSetup.md)
- [ApplySceneViewportRenderPlan](ApplySceneViewportRenderPlan.md)

View File

@@ -19,11 +19,25 @@ using SceneViewportGridPassFactory =
## 当前语义
- 输入是一份已`BuildSceneViewportGridPassData(...)` 组装好的 `InfiniteGridPassData`
- 输出是要追加到 `SceneViewportRenderPlan::postScenePasses`一个 `RenderPass`
- 返回 `nullptr` 时,本帧不会追加网格 pass
- 输入是一份已由 [BuildSceneViewportGridPassData](../ViewportHostRenderFlowUtils/BuildSceneViewportGridPassData.md) 组装好的 `InfiniteGridPassData`
- 输出是要追加到 `SceneViewportRenderPlan::postScenePasses``RenderPass`
- 返回 `nullptr` 时,本帧不会追加 grid pass
## 真实使用位置
`ViewportHostService::BuildSceneViewportRenderState(...)` 会把它绑定到:
- `CreateSceneViewportGridPass(m_sceneViewportGridRenderer, data)`
而 [BuildSceneViewportRenderPlan](BuildSceneViewportRenderPlan.md) 只负责决定是否调用它,并在返回非空时把 pass 收进 plan。
## 设计说明
把“何时需要 grid”与“如何创建 grid pass”拆开是当前 render plan 设计里很重要的一条原则。这样做能让规划层只关心条件判断,而把 renderer 生命周期和 GPU 细节留给 service。
## 相关文档
- [SceneViewportRenderPlan](SceneViewportRenderPlan.md)
- [BuildSceneViewportRenderPlan](BuildSceneViewportRenderPlan.md)
- [BuildSceneViewportGridPassData](../ViewportHostRenderFlowUtils/BuildSceneViewportGridPassData.md)
- [SceneViewportGridPass](../Passes/SceneViewportGridPass/SceneViewportGridPass.md)

View File

@@ -15,17 +15,36 @@ using SceneViewportOverlayPassFactory =
## 作用
描述一个“合成后的 overlay frame data 生成 GPU overlay pass”的工厂回调。
描述一个“根据合成后的 `SceneViewportOverlayFrameData` 生成 editor overlay pass”的工厂回调。
## 当前语义
- 输入是已经合并`SceneViewportOverlayFrameData`
- 输出是要追加到 `SceneViewportRenderPlan::overlayPasses`一个 `RenderPass`
- 输入是已经`SceneViewportOverlayBuilder` 与 gizmo overlay state 合并`SceneViewportOverlayFrameData`
- 输出是要追加到 `SceneViewportRenderPlan::overlayPasses``RenderPass`
- 返回 `nullptr` 时,当前帧不会追加 overlay pass
这让 [BuildSceneViewportRenderPlan](BuildSceneViewportRenderPlan.md) 自己不依赖具体 pass 类型,只负责决定“何时创建 overlay pass、何时跳过”。
## 真实使用位置
`ViewportHostService::BuildSceneViewportRenderState(...)` 当前把它绑定到:
- `CreateSceneViewportEditorOverlayPass(...)`
而 [BuildSceneViewportRenderPlan](BuildSceneViewportRenderPlan.md) 只负责在 `editorOverlayFrameData.HasOverlayPrimitives()` 为真时调用它。
## 设计说明
editor overlay 的重要点不是“它是一个 pass”而是“它消费的是一份 canonical overlay frame data”。
把工厂参数直接设计成 `SceneViewportOverlayFrameData`,意味着:
- hit-test 与最终渲染围绕同一份数据语义展开
- plan 层不需要理解每种 primitive 的 GPU 细节
- `ViewportHostService` 可以自由替换 overlay renderer 的具体实现
## 相关文档
- [SceneViewportRenderPlan](SceneViewportRenderPlan.md)
- [BuildSceneViewportRenderPlan](BuildSceneViewportRenderPlan.md)
- [SceneViewportEditorOverlayData](../SceneViewportEditorOverlayData/SceneViewportEditorOverlayData.md)
- [SceneViewportEditorOverlayPass](../Passes/SceneViewportEditorOverlayPass/SceneViewportEditorOverlayPass.md)
- [Scene View Render Plan And Failure Flow](../../../../_guides/Editor/Scene-Viewport-Render-Plan-And-Failure-Flow.md)

View File

@@ -15,20 +15,42 @@ struct SceneViewportRenderPlanBuildResult {
};
```
## 字段
## 作用
同时返回:
- 本帧构建出的 [SceneViewportRenderPlan](SceneViewportRenderPlan.md)
- 可选 warning 文案
这说明 `BuildSceneViewportRenderPlan(...)` 的结果不是单纯的“成功 / 失败”,而是“规划结果 + 可选降级提示”。
## 字段语义
| 字段 | 类型 | 说明 |
|------|------|------|
| `plan` | `SceneViewportRenderPlan` | 当前帧构建出的渲染计划。 |
| `warningStatusText` | `const char*` | 可选警告文案,用于提示可降级但不必直接终止 Scene View 渲染的缺口。 |
| `plan` | `SceneViewportRenderPlan` | 当前帧构建出的 render plan即便有 warning也仍可能是可执行计划。 |
| `warningStatusText` | `const char*` | 可选 warning 文案,用于提示缺少某项 editor 能力,但不一定要终止 Scene View 渲染。 |
## 当前实现语义
- 即使存在 `warningStatusText``plan` 也仍可能是可执行的有效计划
- 当前最典型的警告来源,是 Scene View 有选中对象、需要 selection outline`objectIdShaderView` 不可用时返回的 `Scene object id shader view is unavailable`
- `warningStatusText == nullptr` 表示当前没有额外 warning
- 当前最典型的 warning 来源,是 Scene View 有选中对象、需要 selection outline`objectIdShaderView` 不可用时返回的 `Scene object id shader view is unavailable`
- `ViewportHostService::BuildSceneViewportRenderState(...)` 会在拿到该结果后,通过 `SetViewportStatusIfEmpty(...)` 尝试保留 warning而不是把它当成硬失败立即终止。
## 设计说明
编辑器渲染里最重要的一条经验是:**能力降级不等于整条链失败**。
例如 selection outline 没法画,并不代表 Scene View 主画面、网格或 gizmo 也应该一起消失。把 warning 从 plan 里显式带出来,能让上层:
- 继续正常渲染
- 同时仍然把缺口通知给用户
这比单纯返回布尔值更适合编辑器。
## 相关文档
- [SceneViewportRenderPlan](SceneViewportRenderPlan.md)
- [BuildSceneViewportRenderPlan](BuildSceneViewportRenderPlan.md)
- [ViewportHostRenderFlowUtils](../ViewportHostRenderFlowUtils/ViewportHostRenderFlowUtils.md)
- [SetViewportStatusIfEmpty](../ViewportHostRenderFlowUtils/SetViewportStatusIfEmpty.md)
- [ViewportHostService](../ViewportHostService/ViewportHostService.md)

View File

@@ -17,15 +17,42 @@ using SceneViewportSelectionOutlinePassFactory = std::function<std::unique_ptr<R
## 作用
描述一个“根据 object-id SRV、选中对象列表和 style 创建 selection outline pass”的工厂回调。
描述一个“根据 object-id SRV、选中对象列表和轮廓样式创建 selection outline pass”的工厂回调。
## 当前语义
- 输入 object-id SRV 必须由上层 render target 流程准备好。
- 输出 pass 会追加到 `SceneViewportRenderPlan::postScenePasses`
- 返回 `nullptr` 时,本帧不会追加 selection outline pass。
- 第一个输入 object-id 纹理的 SRV
- 第二个输入是当前选中对象 id 列表
- 第三个输入是由 [BuildSceneViewportSelectionOutlineStyle](../ViewportHostRenderFlowUtils/BuildSceneViewportSelectionOutlineStyle.md) 生成的默认样式
- 输出 pass 会追加到 `SceneViewportRenderPlan::postScenePasses`
- 返回 `nullptr` 时,本帧不会追加 selection outline pass
## 真实使用位置
`ViewportHostService::BuildSceneViewportRenderState(...)` 当前把它绑定到:
- `CreateSceneViewportSelectionOutlinePass(...)`
而 [BuildSceneViewportRenderPlan](BuildSceneViewportRenderPlan.md) 负责决定:
- 是否存在选中对象
- `objectIdShaderView` 是否可用
- 是否应该生成 warning
## 设计说明
selection outline 是典型的“编辑器强需求,但依赖额外 GPU 资源”的功能。
把它设计成工厂回调,而不是在 plan 层直接 new 某个具体 pass有助于
- 把 object-id 依赖暴露成显式输入
- 在测试里替换成轻量 dummy pass
- 保持 render plan 只关心“需不需要”,不关心“具体 renderer 如何初始化”
## 相关文档
- [SceneViewportRenderPlan](SceneViewportRenderPlan.md)
- [BuildSceneViewportRenderPlan](BuildSceneViewportRenderPlan.md)
- [BuildSceneViewportSelectionOutlineStyle](../ViewportHostRenderFlowUtils/BuildSceneViewportSelectionOutlineStyle.md)
- [ObjectIdOutlineStyle](../../../Rendering/Passes/ObjectIdOutlineStyle/ObjectIdOutlineStyle.md)
- [SceneViewportSelectionOutlinePass](../Passes/SceneViewportSelectionOutlinePass/SceneViewportSelectionOutlinePass.md)

View File

@@ -95,3 +95,4 @@
- [SceneViewportRotateGizmo](SceneViewportRotateGizmo/SceneViewportRotateGizmo.md)
- [SceneViewportScaleGizmo](SceneViewportScaleGizmo/SceneViewportScaleGizmo.md)
- [SceneView Interaction And Gizmo Model](../../../_guides/Editor/SceneView-Interaction-And-Gizmo-Model.md)
- [Scene View Render Plan And Failure Flow](../../../_guides/Editor/Scene-Viewport-Render-Plan-And-Failure-Flow.md)

View File

@@ -82,4 +82,6 @@ Game View 更接近运行时流程:
- [ViewportHostService](ViewportHostService.md)
- [SceneViewportRenderPlan](../SceneViewportRenderPlan/SceneViewportRenderPlan.md)
- [ViewportHostRenderFlowUtils](../ViewportHostRenderFlowUtils/ViewportHostRenderFlowUtils.md)
- [SceneViewportEditorOverlayPass](../Passes/SceneViewportEditorOverlayPass/SceneViewportEditorOverlayPass.md)
- [Scene View Render Plan And Failure Flow](../../../../_guides/Editor/Scene-Viewport-Render-Plan-And-Failure-Flow.md)