From 0c522450550ab927c1e2d120d63a70d9846204c9 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Sat, 4 Apr 2026 14:01:38 +0800 Subject: [PATCH] docs: add viewport host render helper docs --- .../ApplySceneViewportRenderRequestSetup.md | 84 ++++++++ .../ApplyViewportFailureStatus.md | 54 +++++ .../BuildGameViewportRenderFailurePolicy.md | 72 +++++++ .../BuildSceneViewportGridPassData.md | 42 ++++ .../BuildSceneViewportRenderFailurePolicy.md | 84 ++++++++ ...BuildSceneViewportSelectionOutlineStyle.md | 56 ++++++ ...ldViewportRenderTargetUnavailablePolicy.md | 66 +++++++ .../GameViewportRenderFailure.md | 62 ++++++ .../InvalidateViewportObjectIdFrame.md | 53 +++++ .../MarkGameViewportRenderSuccess.md | 55 ++++++ .../MarkSceneViewportRenderSuccess.md | 69 +++++++ .../SceneViewportRenderFailure.md | 64 ++++++ .../SetViewportStatusIfEmpty.md | 56 ++++++ .../ViewportHostRenderFlowUtils.md | 186 ++++++++++++++++++ .../ViewportRenderFallbackPolicy.md | 81 ++++++++ .../BuildViewportColorSurface.md | 35 ++++ .../BuildViewportObjectIdSurface.md | 36 ++++ .../BuildViewportRenderTargetsReuseQuery.md | 40 ++++ .../CreateViewportRenderTargets.md | 46 +++++ .../DestroyViewportRenderTargets.md | 41 ++++ .../ViewportHostRenderTargets.md | 58 ++++++ .../ViewportRenderTargets.md | 39 ++++ 22 files changed, 1379 insertions(+) create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ApplySceneViewportRenderRequestSetup.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ApplyViewportFailureStatus.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildGameViewportRenderFailurePolicy.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildSceneViewportGridPassData.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildSceneViewportRenderFailurePolicy.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildSceneViewportSelectionOutlineStyle.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildViewportRenderTargetUnavailablePolicy.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/GameViewportRenderFailure.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/InvalidateViewportObjectIdFrame.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/MarkGameViewportRenderSuccess.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/MarkSceneViewportRenderSuccess.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/SceneViewportRenderFailure.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/SetViewportStatusIfEmpty.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ViewportHostRenderFlowUtils.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ViewportRenderFallbackPolicy.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/BuildViewportColorSurface.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/BuildViewportObjectIdSurface.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/BuildViewportRenderTargetsReuseQuery.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/CreateViewportRenderTargets.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/DestroyViewportRenderTargets.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/ViewportHostRenderTargets.md create mode 100644 docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/ViewportRenderTargets.md diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ApplySceneViewportRenderRequestSetup.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ApplySceneViewportRenderRequestSetup.md new file mode 100644 index 00000000..e01e1b4a --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ApplySceneViewportRenderRequestSetup.md @@ -0,0 +1,84 @@ +# ApplySceneViewportRenderRequestSetup + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/ViewportHostRenderFlowUtils.h` + +## 签名 + +```cpp +void ApplySceneViewportRenderRequestSetup( + const ViewportRenderTargets& targets, + Rendering::RenderPassSequence* postPasses, + Rendering::CameraRenderRequest& request); +``` + +## 作用 + +把 Scene View 这一帧最基础的附加渲染设置写回 [CameraRenderRequest](../../../Rendering/CameraRenderRequest/CameraRenderRequest.md)。 + +它负责的是“最低层 request 装配”: + +- 重置可能残留的 pass 指针 +- 接入 post-scene pass +- 接入 object-id surface + +它并不负责更高层的 render plan 规划;那部分由 [SceneViewportRenderPlan](../SceneViewportRenderPlan/SceneViewportRenderPlan.md) 负责。 + +## 当前实现行为 + +当前函数会按固定顺序执行: + +1. 清空 `request.preScenePasses` +2. 清空 `request.postScenePasses` +3. 清空 `request.overlayPasses` +4. 把 `request.objectId` 重置成默认值 +5. 只有当 `postPasses != nullptr` 且 `postPasses->GetPassCount() > 0` 时,才重新挂回 `request.postScenePasses` +6. 如果 `targets.objectIdView == nullptr`,直接返回 +7. 否则调用 `BuildViewportObjectIdSurface(targets)` 构建 object-id surface +8. 再把 object-id surface 的 `renderArea` 强制设为 `request.surface.GetRenderArea()` + +## 当前语义重点 + +- 它是“先清空,再按条件重新接线”的写法,目的是防止复用 `CameraRenderRequest` 时残留上一帧指针。 +- object-id 是否可用,只检查 `targets.objectIdView != nullptr`。 +- object-id surface 的渲染区域不会自己重新计算,而是严格跟随当前主 `request.surface` 的 render area。 + +最后一点非常关键,因为 Scene View 可能只渲染目标纹理中的一个子矩形;如果 object-id surface 不同步 render area,拾取和轮廓描边就会与颜色结果错位。 + +## 测试锚点 + +- `ApplySceneRenderRequestSetupAttachesOptionalPassesAndObjectIdSurface` +- `ApplySceneRenderRequestSetupSkipsUnavailableOptionalAttachments` + +这些测试确认了: + +- 只有非空 `postPasses` 才会接入请求 +- object-id surface 会复用深度附件 +- object-id surface 的 render area 与主 surface 完全一致 +- object-id 资源不可用时,旧配置会被正确清空 + +## 真实使用位置 + +- [ApplySceneViewportRenderPlan](../SceneViewportRenderPlan/ApplySceneViewportRenderPlan.md) 会先调用本函数,再补充 overlay pass 和 clear-color override。 +- `tests/Editor/test_viewport_render_flow_utils.cpp` 直接把它当成 Scene View request 基础装配入口进行测试。 + +## 设计说明 + +把 Scene View request 的基础装配提炼成一个小 helper,是为了维持分层清晰: + +- `ViewportHostService` 决定什么时候渲染 +- `SceneViewportRenderPlan` 决定额外挂哪些 pass +- 本函数只负责把最基础、最容易出错的 request 连接动作做对 + +这跟很多商业引擎内部的 render request builder 很像: 先保证 attachment / sub-viewport / auxiliary buffer 对齐,再谈更高层的编辑器叠加效果。 + +## 相关文档 + +- [SceneViewportRenderPlan](../SceneViewportRenderPlan/SceneViewportRenderPlan.md) +- [ApplySceneViewportRenderPlan](../SceneViewportRenderPlan/ApplySceneViewportRenderPlan.md) +- [ViewportHostRenderTargets](../ViewportHostRenderTargets/ViewportHostRenderTargets.md) +- [CameraRenderRequest](../../../Rendering/CameraRenderRequest/CameraRenderRequest.md) +- [ObjectIdRenderRequest](../../../Rendering/CameraRenderRequest/ObjectIdRenderRequest/ObjectIdRenderRequest.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ApplyViewportFailureStatus.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ApplyViewportFailureStatus.md new file mode 100644 index 00000000..8fa0ab99 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ApplyViewportFailureStatus.md @@ -0,0 +1,54 @@ +# ApplyViewportFailureStatus + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/ViewportHostRenderFlowUtils.h` + +## 签名 + +```cpp +void ApplyViewportFailureStatus( + std::string& statusText, + const ViewportRenderFallbackPolicy& policy); +``` + +## 作用 + +根据 [ViewportRenderFallbackPolicy](ViewportRenderFallbackPolicy.md) 把失败文案写回视口状态字符串。 + +它只负责“文字状态”这一件事,不处理清屏,也不处理 object-id 帧失效;这些动作由 `ViewportHostService::ApplyViewportRenderFailure(...)` 在更高一层统一执行。 + +## 当前实现行为 + +当前逻辑很直接: + +1. 如果 `policy.statusText == nullptr`,直接返回。 +2. 如果 `policy.setStatusIfEmpty == true`,调用 [SetViewportStatusIfEmpty](SetViewportStatusIfEmpty.md)。 +3. 否则直接覆盖 `statusText`。 + +## 测试锚点 + +`ApplyViewportFailureStatusRespectsSetIfEmptyBehavior` 明确覆盖了三种情况: + +- 空字符串时,`SceneRendererFailed` 可以写入 `Scene renderer failed` +- 原本已有更具体文案时,`setStatusIfEmpty == true` 不会覆盖 +- `GameViewportRenderFailure::NoActiveScene` 这类普通失败会直接覆盖 + +## 设计说明 + +把“失败状态如何写文字”单独抽成 helper,有两个现实收益: + +- `ViewportRenderFallbackPolicy` 可以把 UI 文案策略和清屏策略一起定义,但不把执行动作塞进数据结构本身 +- Scene View 可以安全保留更具体的 warning,而 Game View 仍然可以使用覆盖式语义 + +这类拆分和商业引擎里编辑器状态系统很像:统一回退入口负责调度,而不同反馈通道各自有单独规则。 + +## 相关文档 + +- [ViewportRenderFallbackPolicy](ViewportRenderFallbackPolicy.md) +- [SetViewportStatusIfEmpty](SetViewportStatusIfEmpty.md) +- [BuildSceneViewportRenderFailurePolicy](BuildSceneViewportRenderFailurePolicy.md) +- [BuildGameViewportRenderFailurePolicy](BuildGameViewportRenderFailurePolicy.md) +- [ViewportHostService](../ViewportHostService/ViewportHostService.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildGameViewportRenderFailurePolicy.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildGameViewportRenderFailurePolicy.md new file mode 100644 index 00000000..4ffd0ee8 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildGameViewportRenderFailurePolicy.md @@ -0,0 +1,72 @@ +# BuildGameViewportRenderFailurePolicy + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/ViewportHostRenderFlowUtils.h` + +## 签名 + +```cpp +ViewportRenderFallbackPolicy BuildGameViewportRenderFailurePolicy( + GameViewportRenderFailure failure); +``` + +## 作用 + +把 [GameViewportRenderFailure](GameViewportRenderFailure.md) 枚举值转换成 Game View 的回退策略。 + +## 当前实现行为 + +当前实现同样会先设置: + +```cpp +policy.shouldClear = true; +``` + +随后按失败类型填充文案与颜色: + +| 失败类型 | 状态文案 | 清屏颜色 | +|------|------|------| +| `NoActiveScene` | `No active scene` | `(0.07, 0.08, 0.10, 1.0)` | +| `NoCameraInScene` | `No camera in scene` | `(0.10, 0.09, 0.08, 1.0)` | +| `SceneRendererFailed` | `Scene renderer failed` | `(0.18, 0.07, 0.07, 1.0)` | + +其余字段保持默认值: + +- `setStatusIfEmpty = false` +- `invalidateObjectIdFrame = true` + +## 真实使用位置 + +`ViewportHostService::RenderGameViewportEntry(...)` 在下面三种失败路径使用本函数: + +- 没有活动场景 +- 场景里没有任何 `CameraComponent` +- `m_sceneRenderer->Render(*scene, nullptr, ...)` 失败 + +## 测试锚点 + +`BuildFailurePoliciesExposeExpectedStatusAndClearBehavior` 验证了: + +- `NoCameraInScene` 的文案 +- `shouldClear == true` +- 清屏颜色是 `(0.10, 0.09, 0.08, 1.0)` + +## 设计说明 + +Game View 的目标是尽量接近运行时结果,因此失败反馈策略更像“简洁而明确的播放器错误状态”: + +- 没有场景 +- 没有相机 +- renderer 失败 + +它不需要像 Scene View 那样保存更多编辑器工具 warning,也就没有 `setStatusIfEmpty` 这类优先级处理需求。 + +## 相关文档 + +- [GameViewportRenderFailure](GameViewportRenderFailure.md) +- [ViewportRenderFallbackPolicy](ViewportRenderFallbackPolicy.md) +- [ApplyViewportFailureStatus](ApplyViewportFailureStatus.md) +- [ViewportHostService](../ViewportHostService/ViewportHostService.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildSceneViewportGridPassData.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildSceneViewportGridPassData.md new file mode 100644 index 00000000..02d83016 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildSceneViewportGridPassData.md @@ -0,0 +1,42 @@ +# BuildSceneViewportGridPassData + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/ViewportHostRenderFlowUtils.h` + +## 签名 + +```cpp +Rendering::Passes::InfiniteGridPassData BuildSceneViewportGridPassData( + const SceneViewportOverlayData& overlay); +``` + +## 作用 + +从当前 Scene View overlay 数据构造 grid pass 所需的 `InfiniteGridPassData`。 + +## 当前实现行为 + +- 当前只做字段拷贝,不创建真正的 pass 对象。 +- 会复制: + - `valid` + - `cameraPosition` + - `cameraForward` + - `cameraRight` + - `cameraUp` + - `verticalFovDegrees` + - `nearClipPlane` + - `farClipPlane` + - `orbitDistance` + +## 测试覆盖 + +`tests/Editor/test_viewport_render_flow_utils.cpp` 当前验证了它会正确拷贝 Scene View 相机相关字段。 + +## 相关文档 + +- [SceneViewportEditorOverlayData](../SceneViewportEditorOverlayData/SceneViewportEditorOverlayData.md) +- [SceneViewportGridPassFactory](../SceneViewportRenderPlan/SceneViewportGridPassFactory.md) +- [CreateSceneViewportGridPass](../Passes/SceneViewportGridPass/CreateSceneViewportGridPass.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildSceneViewportRenderFailurePolicy.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildSceneViewportRenderFailurePolicy.md new file mode 100644 index 00000000..97bb6a60 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildSceneViewportRenderFailurePolicy.md @@ -0,0 +1,84 @@ +# BuildSceneViewportRenderFailurePolicy + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/ViewportHostRenderFlowUtils.h` + +## 签名 + +```cpp +ViewportRenderFallbackPolicy BuildSceneViewportRenderFailurePolicy( + SceneViewportRenderFailure failure); +``` + +## 作用 + +把 [SceneViewportRenderFailure](SceneViewportRenderFailure.md) 枚举值转换成 Scene View 专用的回退策略。 + +返回结果不仅包含文案,还明确规定: + +- 是否清屏 +- 清成什么颜色 +- 是否保留已有 warning +- 是否让 object-id 帧失效 + +## 当前实现行为 + +当前实现会先设置: + +```cpp +policy.shouldClear = true; +``` + +然后按失败类型填充细节: + +| 失败类型 | 状态文案 | 清屏颜色 | `setStatusIfEmpty` | +|------|------|------|------| +| `MissingSceneViewCamera` | `Scene view camera is unavailable` | `(0.18, 0.07, 0.07, 1.0)` | `false` | +| `NoActiveScene` | `No active scene` | `(0.07, 0.08, 0.10, 1.0)` | `false` | +| `SceneRendererFailed` | `Scene renderer failed` | `(0.18, 0.07, 0.07, 1.0)` | `true` | + +`invalidateObjectIdFrame` 沿用默认值 `true`。 + +## 真实使用位置 + +`ViewportHostService::RenderSceneViewportEntry(...)` 在以下路径会调用本函数: + +- Scene View 相机不可用 +- 当前没有活动场景 +- `BuildRenderRequests(...)` 返回空 +- `m_sceneRenderer->Render(requests)` 失败 + +生成的策略会被 `ApplyViewportRenderFailure(...)` 消费,最终落到: + +- 状态文字更新 +- object-id 帧失效 +- 颜色 / 深度缓冲清理 + +## 测试锚点 + +`BuildFailurePoliciesExposeExpectedStatusAndClearBehavior` 明确验证了: + +- `MissingSceneViewCamera` 的红色清屏值 +- `SceneRendererFailed` 的 `setStatusIfEmpty == true` + +`ApplyViewportFailureStatusRespectsSetIfEmptyBehavior` 则验证了 `SceneRendererFailed` 不会覆盖已存在的更具体 warning。 + +## 设计说明 + +Scene View 不是纯运行时画面,而是诊断和编辑工具本身的一部分,所以失败反馈必须同时兼顾“可见”和“可解释”: + +- `NoActiveScene` 用偏冷的灰蓝色,表达“当前无内容可编辑” +- 相机缺失或 renderer 失败用偏红色,强调这是异常状态 + +更重要的一点是 `SceneRendererFailed` 使用 `setStatusIfEmpty = true`。这允许 Scene View 先保留诸如 `Scene object id shader view is unavailable` 之类更具体的 warning,再在需要时回退到通用失败文案。这样的优先级处理,比简单覆盖式状态系统更适合编辑器。 + +## 相关文档 + +- [SceneViewportRenderFailure](SceneViewportRenderFailure.md) +- [ViewportRenderFallbackPolicy](ViewportRenderFallbackPolicy.md) +- [ApplyViewportFailureStatus](ApplyViewportFailureStatus.md) +- [SceneViewportRenderPlan](../SceneViewportRenderPlan/SceneViewportRenderPlan.md) +- [ViewportHostService](../ViewportHostService/ViewportHostService.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildSceneViewportSelectionOutlineStyle.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildSceneViewportSelectionOutlineStyle.md new file mode 100644 index 00000000..07881ded --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildSceneViewportSelectionOutlineStyle.md @@ -0,0 +1,56 @@ +# BuildSceneViewportSelectionOutlineStyle + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/ViewportHostRenderFlowUtils.h` + +## 签名 + +```cpp +Rendering::Passes::ObjectIdOutlineStyle BuildSceneViewportSelectionOutlineStyle( + bool debugSelectionMask = false); +``` + +## 作用 + +生成 Scene View 选中轮廓 pass 的默认样式配置。 + +## 当前实现行为 + +当前实现返回的样式是固定值: + +- `outlineColor = (1.0, 0.4, 0.0, 1.0)` +- `outlineWidthPixels = 2.0` +- `debugSelectionMask =` 直接透传传入参数 + +也就是说,当前 Scene View 默认使用橙色 `2px` 轮廓,而 debug mask 只是额外的调试开关,不会改变主样式。 + +## 测试锚点 + +`BuildSceneViewportSelectionOutlineStyleAppliesSceneDefaults` 验证了: + +- 颜色固定为橙色 +- 线宽固定为 `2.0` +- `debugSelectionMask` 参数会被正确透传 + +## 真实使用位置 + +[BuildSceneViewportRenderPlan](../SceneViewportRenderPlan/BuildSceneViewportRenderPlan.md) 在为当前选中对象创建 selection outline pass 之前,会调用本函数构造 `ObjectIdOutlineStyle`。 + +## 设计说明 + +把默认轮廓样式收敛到一个 helper,而不是散落在 pass 构建代码里,有两个好处: + +- 编辑器主题或视觉规范后续如果要统一调整,只需要改一个入口 +- render plan 构建逻辑仍然聚焦“要不要创建这个 pass”,而不是混入具体的样式细节 + +这种做法也符合商业引擎常见的 Editor 可视化设计思路:默认视觉语言稳定统一,调试开关单独暴露。 + +## 相关文档 + +- [SceneViewportRenderPlan](../SceneViewportRenderPlan/SceneViewportRenderPlan.md) +- [BuildSceneViewportRenderPlan](../SceneViewportRenderPlan/BuildSceneViewportRenderPlan.md) +- [ObjectIdOutlineStyle](../../../Rendering/Passes/ObjectIdOutlineStyle/ObjectIdOutlineStyle.md) +- [SceneViewportSelectionOutlinePass](../Passes/SceneViewportSelectionOutlinePass/SceneViewportSelectionOutlinePass.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildViewportRenderTargetUnavailablePolicy.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildViewportRenderTargetUnavailablePolicy.md new file mode 100644 index 00000000..aaa8af00 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/BuildViewportRenderTargetUnavailablePolicy.md @@ -0,0 +1,66 @@ +# BuildViewportRenderTargetUnavailablePolicy + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/ViewportHostRenderFlowUtils.h` + +## 签名 + +```cpp +ViewportRenderFallbackPolicy BuildViewportRenderTargetUnavailablePolicy(); +``` + +## 作用 + +生成“视口 render target 当前不可用”时的回退策略。 + +这条路径发生在真正进入 Scene / Game 渲染之前,因此它不是“渲染失败后的清屏策略”,而是“连可用目标都没有时的诊断策略”。 + +## 当前返回值语义 + +当前实现只做了一件事: + +- `policy.statusText = "Viewport render target is unavailable"` + +其余字段沿用 [ViewportRenderFallbackPolicy](ViewportRenderFallbackPolicy.md) 的默认值,因此最终效果是: + +- 不清屏 +- 默认保持 `invalidateObjectIdFrame = true` + +## 真实使用位置 + +`ViewportHostService::RenderViewportEntry(...)` 会在下面条件成立时直接使用这条策略: + +```cpp +entry.renderTargets.colorView == nullptr || entry.renderTargets.depthView == nullptr +``` + +随后它会: + +- 调用 `ApplyViewportFailureStatus(...)` +- 调用 `InvalidateViewportObjectIdFrame(...)` +- 立即返回,不再尝试构建 `RenderSurface` + +## 测试锚点 + +`BuildFailurePoliciesExposeExpectedStatusAndClearBehavior` 确认了: + +- 文案是 `Viewport render target is unavailable` +- `shouldClear == false` +- `invalidateObjectIdFrame == true` + +## 设计说明 + +这里故意不清屏,是因为问题的本质不是“上一帧内容不对”,而是“本帧根本没有可写的目标”。 + +如果连颜色 / 深度 view 都缺失,继续走清屏语义没有意义,甚至可能掩盖真正的资源问题。对编辑器用户而言,更重要的是尽快给出明确文案,并阻止后续 object-id 功能继续使用旧数据。 + +## 相关文档 + +- [ViewportRenderFallbackPolicy](ViewportRenderFallbackPolicy.md) +- [ApplyViewportFailureStatus](ApplyViewportFailureStatus.md) +- [InvalidateViewportObjectIdFrame](InvalidateViewportObjectIdFrame.md) +- [ViewportHostRenderTargets](../ViewportHostRenderTargets/ViewportHostRenderTargets.md) +- [ViewportHostService](../ViewportHostService/ViewportHostService.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/GameViewportRenderFailure.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/GameViewportRenderFailure.md new file mode 100644 index 00000000..230461f3 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/GameViewportRenderFailure.md @@ -0,0 +1,62 @@ +# GameViewportRenderFailure + +**命名空间**: `XCEngine::Editor` + +**类型**: `enum class` + +**源文件**: `editor/src/Viewport/ViewportHostRenderFlowUtils.h` + +## 定义 + +```cpp +enum class GameViewportRenderFailure { + NoActiveScene, + NoCameraInScene, + SceneRendererFailed +}; +``` + +## 作用 + +表达 Game View 渲染路径里会被归类为用户可见回退状态的失败类别。 + +和 [SceneViewportRenderFailure](SceneViewportRenderFailure.md) 一样,它是编辑器层的失败分类,而不是底层渲染错误码。 + +## 枚举值语义 + +| 枚举值 | 含义 | +|------|------| +| `NoActiveScene` | 当前没有活动场景。 | +| `NoCameraInScene` | 活动场景存在,但没有任何 `CameraComponent` 可供 Game View 使用。 | +| `SceneRendererFailed` | `SceneRenderer` 无法成功执行当前 Game View 渲染。 | + +## 当前实现行为 + +在 `ViewportHostService::RenderGameViewportEntry(...)` 中: + +1. `scene == nullptr` 时返回 `NoActiveScene`。 +2. `scene->FindObjectsOfType()` 为空时返回 `NoCameraInScene`。 +3. `m_sceneRenderer->Render(*scene, nullptr, ...)` 失败时返回 `SceneRendererFailed`。 + +这些枚举值会被 [BuildGameViewportRenderFailurePolicy](BuildGameViewportRenderFailurePolicy.md) 转成对应的清屏颜色和状态文字。 + +## 设计说明 + +Game View 的职责比 Scene View 更接近“真实运行时预览”,因此这里的失败类别刻意保持简单: + +- 没场景 +- 没相机 +- renderer 失败 + +它不承担 Scene View 那种工具链 warning 的解释任务,所以不需要 `MissingSceneViewCamera` 或 object-id 相关类别。 + +## 真实使用位置 + +- `ViewportHostService::RenderGameViewportEntry(...)` +- [BuildGameViewportRenderFailurePolicy](BuildGameViewportRenderFailurePolicy.md) + +## 相关文档 + +- [BuildGameViewportRenderFailurePolicy](BuildGameViewportRenderFailurePolicy.md) +- [ViewportRenderFallbackPolicy](ViewportRenderFallbackPolicy.md) +- [ViewportHostService](../ViewportHostService/ViewportHostService.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/InvalidateViewportObjectIdFrame.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/InvalidateViewportObjectIdFrame.md new file mode 100644 index 00000000..8167b8b3 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/InvalidateViewportObjectIdFrame.md @@ -0,0 +1,53 @@ +# InvalidateViewportObjectIdFrame + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/ViewportHostRenderFlowUtils.h` + +## 签名 + +```cpp +void InvalidateViewportObjectIdFrame(ViewportRenderTargets& targets); +``` + +## 作用 + +把当前视口的 object-id 帧标记为无效,防止拾取、轮廓高亮或其他依赖 object-id 结果的编辑器功能继续误用上一帧数据。 + +## 当前实现行为 + +当前实现只有一行: + +```cpp +targets.hasValidObjectIdFrame = false; +``` + +它不会销毁资源,也不会清空纹理内容;它只更新“这份 object-id 结果还能不能被当成有效帧使用”的状态位。 + +## 真实使用位置 + +- `ViewportHostService::ApplyViewportRenderFailure(...)` + - 当策略要求 `invalidateObjectIdFrame == true` 时调用 +- `ViewportHostService::RenderViewportEntry(...)` + - render target 缺失时立即调用 + +## 设计说明 + +编辑器里 object-id buffer 的问题通常不是“有没有纹理”,而是“纹理里的内容还是不是这一帧对应的真实结果”。 + +单独维护 `hasValidObjectIdFrame` 的意义在于: + +- GPU 资源可以继续复用 +- 但交互层不会把陈旧帧误判成有效拾取结果 + +这比每次失败都销毁 object-id 资源更稳,也更符合实时编辑器的性能要求。 + +## 相关文档 + +- [ViewportHostRenderTargets](../ViewportHostRenderTargets/ViewportHostRenderTargets.md) +- [ViewportRenderFallbackPolicy](ViewportRenderFallbackPolicy.md) +- [MarkSceneViewportRenderSuccess](MarkSceneViewportRenderSuccess.md) +- [MarkGameViewportRenderSuccess](MarkGameViewportRenderSuccess.md) +- [ViewportHostService](../ViewportHostService/ViewportHostService.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/MarkGameViewportRenderSuccess.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/MarkGameViewportRenderSuccess.md new file mode 100644 index 00000000..b029e4a6 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/MarkGameViewportRenderSuccess.md @@ -0,0 +1,55 @@ +# MarkGameViewportRenderSuccess + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/ViewportHostRenderFlowUtils.h` + +## 签名 + +```cpp +void MarkGameViewportRenderSuccess(ViewportRenderTargets& targets); +``` + +## 作用 + +在 Game View 渲染成功后,写回最基本的资源状态,并明确让 object-id 帧失效。 + +## 当前实现行为 + +当前实现只做两件事: + +```cpp +targets.colorState = RHI::ResourceStates::PixelShaderResource; +targets.hasValidObjectIdFrame = false; +``` + +注意它不会修改 `targets.objectIdState`。这是符合当前实现语义的,因为 Game View 路径本身并不依赖 Scene View 的 object-id 结果。 + +## 测试锚点 + +`MarkGameRenderSuccessClearsObjectIdFrameAndUpdatesColorState` 验证了: + +- `colorState` 会被切到 `PixelShaderResource` +- `hasValidObjectIdFrame` 会被强制清成 `false` + +## 真实使用位置 + +`ViewportHostService::RenderGameViewportEntry(...)` 在 `m_sceneRenderer->Render(*scene, nullptr, ...)` 成功后调用本函数。 + +## 设计说明 + +Game View 的目标是展示运行时相机结果,而不是服务编辑器拾取工具,所以成功渲染后最合理的做法不是“沿用上一帧 Scene View 的 object-id 状态”,而是明确把它视为无效。 + +这能避免跨视口共享状态时出现隐蔽错误,例如: + +- Game View 画面对了 +- 但编辑器仍然误以为有一份可用于拾取的 object-id 帧 + +## 相关文档 + +- [ViewportHostRenderTargets](../ViewportHostRenderTargets/ViewportHostRenderTargets.md) +- [MarkSceneViewportRenderSuccess](MarkSceneViewportRenderSuccess.md) +- [GameViewportRenderFailure](GameViewportRenderFailure.md) +- [ViewportHostService](../ViewportHostService/ViewportHostService.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/MarkSceneViewportRenderSuccess.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/MarkSceneViewportRenderSuccess.md new file mode 100644 index 00000000..b3fcf463 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/MarkSceneViewportRenderSuccess.md @@ -0,0 +1,69 @@ +# MarkSceneViewportRenderSuccess + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/ViewportHostRenderFlowUtils.h` + +## 签名 + +```cpp +void MarkSceneViewportRenderSuccess( + ViewportRenderTargets& targets, + const Rendering::CameraRenderRequest& request); +``` + +## 作用 + +在 Scene View 渲染成功后,把 `ViewportRenderTargets` 的资源状态和 object-id 帧有效性更新到下一阶段可消费的状态。 + +## 当前实现行为 + +当前实现会写入三件事: + +```cpp +targets.colorState = RHI::ResourceStates::PixelShaderResource; +targets.objectIdState = RHI::ResourceStates::PixelShaderResource; +targets.hasValidObjectIdFrame = request.objectId.IsRequested(); +``` + +这意味着: + +- Scene View 颜色纹理会被标记成可供后续采样的 `PixelShaderResource` +- object-id 纹理也会进入同样的采样状态 +- 只有当当前 request 实际请求了 object-id surface,`hasValidObjectIdFrame` 才会被标记为有效 + +## 测试锚点 + +`MarkSceneRenderSuccessMovesTargetsToShaderResourceState` 覆盖了两种情况: + +- object-id 已请求时,`hasValidObjectIdFrame == true` +- object-id 未请求时,`hasValidObjectIdFrame == false` + +两种情况下,`colorState` 和 `objectIdState` 都会被切到 `PixelShaderResource`。 + +## 真实使用位置 + +`ViewportHostService::RenderSceneViewportEntry(...)` 在 `m_sceneRenderer->Render(requests)` 成功后立即调用本函数。 + +这是 Scene View 渲染链里非常关键的“成功收尾”步骤,因为后续: + +- ImGui 需要采样颜色结果 +- selection outline / object-id picker 依赖 object-id 纹理 + +## 设计说明 + +渲染成功并不等于后续编辑器工具可以安全读取结果;还必须显式把资源状态和“本帧是否有效”这两个条件整理好。 + +把这一步收口成 helper 的价值在于: + +- 渲染主流程不用重复书写状态回写代码 +- object-id 是否真的有效,始终以 request 是否请求过它为准,而不是凭资源是否存在做猜测 + +## 相关文档 + +- [ViewportHostRenderTargets](../ViewportHostRenderTargets/ViewportHostRenderTargets.md) +- [ApplySceneViewportRenderRequestSetup](ApplySceneViewportRenderRequestSetup.md) +- [MarkGameViewportRenderSuccess](MarkGameViewportRenderSuccess.md) +- [ViewportHostService](../ViewportHostService/ViewportHostService.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/SceneViewportRenderFailure.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/SceneViewportRenderFailure.md new file mode 100644 index 00000000..45268c2c --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/SceneViewportRenderFailure.md @@ -0,0 +1,64 @@ +# SceneViewportRenderFailure + +**命名空间**: `XCEngine::Editor` + +**类型**: `enum class` + +**源文件**: `editor/src/Viewport/ViewportHostRenderFlowUtils.h` + +## 定义 + +```cpp +enum class SceneViewportRenderFailure { + MissingSceneViewCamera, + NoActiveScene, + SceneRendererFailed +}; +``` + +## 作用 + +表达 Scene View 渲染链里当前被文档化、且会映射为用户可见回退策略的失败类别。 + +它不是底层 renderer 错误码,也不是异常系统;它更像 Editor UI 语义层的“失败原因分类”,专门服务于 [BuildSceneViewportRenderFailurePolicy](BuildSceneViewportRenderFailurePolicy.md)。 + +## 枚举值语义 + +| 枚举值 | 含义 | +|------|------| +| `MissingSceneViewCamera` | 编辑器内部 Scene View 相机不可用,连构建 Scene View request 的前提都不满足。 | +| `NoActiveScene` | 当前没有活动场景,因此没有任何内容可供 Scene View 渲染。 | +| `SceneRendererFailed` | `SceneRenderer` 没有成功产出或执行可用 request。 | + +## 当前实现行为 + +在 `ViewportHostService::RenderSceneViewportEntry(...)` 中,这三个值分别对应三段失败路径: + +1. `EnsureSceneViewCamera()` 失败。 +2. `scene == nullptr`。 +3. `BuildRenderRequests(...)` 返回空,或 `Render(requests)` 执行失败。 + +随后这些枚举值会交给 [BuildSceneViewportRenderFailurePolicy](BuildSceneViewportRenderFailurePolicy.md),转成具体的状态文案、清屏颜色和 object-id 失效策略。 + +## 设计说明 + +这里没有把 Scene View 的每一种技术性失败都暴露成一个独立枚举,而是只保留对编辑器用户真正有诊断价值的粗粒度类别。 + +这种做法接近商业引擎里 Scene 视口常见的处理方式: + +- 用户首先需要知道“现在为什么没画出来”。 +- 但不一定需要知道底层每一个 GPU / 资源细节。 + +更细的上下文,例如 `objectIdShaderView` 缺失这类可降级 warning,则由上层状态文字补充,而不是继续膨胀失败枚举。 + +## 真实使用位置 + +- `ViewportHostService::RenderSceneViewportEntry(...)` +- [BuildSceneViewportRenderFailurePolicy](BuildSceneViewportRenderFailurePolicy.md) + +## 相关文档 + +- [BuildSceneViewportRenderFailurePolicy](BuildSceneViewportRenderFailurePolicy.md) +- [ViewportRenderFallbackPolicy](ViewportRenderFallbackPolicy.md) +- [ViewportHostService](../ViewportHostService/ViewportHostService.md) +- [SceneViewportRenderPlan](../SceneViewportRenderPlan/SceneViewportRenderPlan.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/SetViewportStatusIfEmpty.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/SetViewportStatusIfEmpty.md new file mode 100644 index 00000000..478c4def --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/SetViewportStatusIfEmpty.md @@ -0,0 +1,56 @@ +# SetViewportStatusIfEmpty + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/ViewportHostRenderFlowUtils.h` + +## 签名 + +```cpp +void SetViewportStatusIfEmpty(std::string& statusText, const char* message); +``` + +## 作用 + +只在当前视口状态文字为空时写入一条消息。 + +这是一种很小但很关键的 helper,因为编辑器视口经常会同时遇到: + +- 更具体的 warning +- 更泛化的失败文案 + +此函数允许前者优先保留。 + +## 当前实现行为 + +当前实现只有一个判断: + +- 如果 `statusText.empty()`,则写入 `message` +- 否则保持原值不变 + +它不会做空指针检查,也不会拼接字符串,因此调用方需要先决定“这条消息是否值得保留为首要状态”。 + +## 真实使用位置 + +当前至少有三类直接使用场景: + +- `ViewportHostService::PickSceneViewEntity(...)` + - object-id 读回失败时,尝试写入 `Scene object id readback failed` +- `ViewportHostService::BuildSceneViewportRenderState(...)` + - render plan 返回非致命 warning 时,尝试保留该 warning +- [ApplyViewportFailureStatus](ApplyViewportFailureStatus.md) + - 当策略要求 `setStatusIfEmpty == true` 时,会转而调用本函数 + +## 设计说明 + +编辑器状态文案的设计重点不是“最后一个错误覆盖前面的错误”,而是“尽量保留最有诊断价值的那条信息”。 + +例如 Scene View 已经先得到了 `Scene object id shader view is unavailable` 这样的精确 warning,后续 `SceneRendererFailed` 不应该粗暴覆盖掉它;否则用户只能看到更笼统的失败结果,看不到真正值得排查的上下文。 + +## 相关文档 + +- [ApplyViewportFailureStatus](ApplyViewportFailureStatus.md) +- [BuildSceneViewportRenderFailurePolicy](BuildSceneViewportRenderFailurePolicy.md) +- [ViewportHostService](../ViewportHostService/ViewportHostService.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ViewportHostRenderFlowUtils.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ViewportHostRenderFlowUtils.md new file mode 100644 index 00000000..5b163d38 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ViewportHostRenderFlowUtils.md @@ -0,0 +1,186 @@ +# ViewportHostRenderFlowUtils + +**命名空间**: `XCEngine::Editor` + +**类型**: `structs + enums + header-helper` + +**源文件**: `editor/src/Viewport/ViewportHostRenderFlowUtils.h` + +**描述**: 为 `ViewportHostService` 提供视口失败回退策略、Scene View request 基础装配以及渲染成功后的状态回写 helper。 + +## 概览 + +`ViewportHostRenderFlowUtils.h` 处在 [ViewportHostService](../ViewportHostService/ViewportHostService.md) 的主流程中段,承担的是“把渲染流程里反复出现、但又不值得塞进 service 主体的大量小规则收拢起来”的职责。 + +它当前主要覆盖三类问题: + +- 失败回退 + - 视口应该显示什么状态文案 + - 是否需要清屏 + - object-id 帧是否必须作废 +- Scene View request 基础装配 + - 如何清理旧的 pass 指针 + - 何时接入 `postScenePasses` + - 何时接入 object-id surface +- 成功后的状态回写 + - 颜色 / object-id 资源该切回什么状态 + - 当前 object-id 帧是否可供下一阶段消费 + +在更早的版本里,这类逻辑很容易全部堆进 `ViewportHostService::RenderSceneViewportEntry(...)` / `RenderGameViewportEntry(...)`。但随着 Scene View 逐步加入网格、选中轮廓、overlay、object-id 和失败诊断,这种写法会迅速变成难维护的“业务大函数”。 + +当前的拆分更接近商业级游戏引擎编辑器常见的组织方式: + +- service 负责总调度 +- render plan 负责附加 pass 规划 +- flow utils 负责失败策略、基础 request 接线和状态回写 + +## 与 `SceneViewportRenderPlan` 的分工 + +[SceneViewportRenderPlan](../SceneViewportRenderPlan/SceneViewportRenderPlan.md) 和本头文件经常一起出现,但职责并不相同: + +- `SceneViewportRenderPlan` + - 负责决定 Scene View 这一帧“额外挂哪些 pass” + - 例如 grid、selection outline、editor overlay +- `ViewportHostRenderFlowUtils` + - 负责“失败时怎么退、请求基础接线怎么做、成功后怎么收尾” + +换句话说,`SceneViewportRenderPlan` 更像“内容规划层”,而这里更像“流程辅助层”。 + +这种拆法的价值在于: + +- render plan 可以独立测试“要不要挂 pass” +- flow utils 可以独立测试“失败 / 成功状态到底怎样回写” +- `ViewportHostService` 自己保留清晰的主调用链,而不是被一堆细枝末节淹没 + +## 公开类型与函数 + +| 成员 | 说明 | +|------|------| +| [ViewportRenderFallbackPolicy](ViewportRenderFallbackPolicy.md) | 统一描述失败文案、清屏动作与 object-id 失效策略。 | +| [SceneViewportRenderFailure](SceneViewportRenderFailure.md) | Scene View 的失败分类。 | +| [GameViewportRenderFailure](GameViewportRenderFailure.md) | Game View 的失败分类。 | +| [SetViewportStatusIfEmpty](SetViewportStatusIfEmpty.md) | 仅在状态文字为空时写入消息。 | +| [ApplyViewportFailureStatus](ApplyViewportFailureStatus.md) | 按失败策略写回状态文字。 | +| [InvalidateViewportObjectIdFrame](InvalidateViewportObjectIdFrame.md) | 让 object-id 帧标记失效。 | +| [BuildViewportRenderTargetUnavailablePolicy](BuildViewportRenderTargetUnavailablePolicy.md) | 构建“render target 不可用”策略。 | +| [BuildSceneViewportRenderFailurePolicy](BuildSceneViewportRenderFailurePolicy.md) | 把 Scene View 失败分类转成回退策略。 | +| [BuildGameViewportRenderFailurePolicy](BuildGameViewportRenderFailurePolicy.md) | 把 Game View 失败分类转成回退策略。 | +| [BuildSceneViewportGridPassData](BuildSceneViewportGridPassData.md) | 把 Scene View overlay 相机状态转换为 `InfiniteGridPassData`。 | +| [BuildSceneViewportSelectionOutlineStyle](BuildSceneViewportSelectionOutlineStyle.md) | 生成 Scene View 选中轮廓默认样式。 | +| [ApplySceneViewportRenderRequestSetup](ApplySceneViewportRenderRequestSetup.md) | 为 Scene View 基础 request 接线。 | +| [MarkSceneViewportRenderSuccess](MarkSceneViewportRenderSuccess.md) | Scene View 成功后的状态回写。 | +| [MarkGameViewportRenderSuccess](MarkGameViewportRenderSuccess.md) | Game View 成功后的状态回写。 | + +## `ViewportHostService` 调用链中的位置 + +### 视口入口 + +`ViewportHostService::RenderViewportEntry(...)` 先检查 `colorView` / `depthView` 是否可用。 + +如果 render target 缺失,它不会继续走渲染,而是直接: + +1. 调用 [BuildViewportRenderTargetUnavailablePolicy](BuildViewportRenderTargetUnavailablePolicy.md) +2. 调用 [ApplyViewportFailureStatus](ApplyViewportFailureStatus.md) +3. 调用 [InvalidateViewportObjectIdFrame](InvalidateViewportObjectIdFrame.md) + +这是一条“资源前置条件失败”路径。 + +### Scene View 路径 + +`ViewportHostService::RenderSceneViewportEntry(...)` 当前大致是下面这条链: + +1. 检查编辑器 Scene View 相机是否存在 +2. 没有活动场景时走 [BuildSceneViewportRenderFailurePolicy](BuildSceneViewportRenderFailurePolicy.md) +3. 构建 [SceneViewportRenderPlan](../SceneViewportRenderPlan/SceneViewportRenderPlan.md) +4. 调用 `SceneRenderer::BuildRenderRequests(...)` +5. 调用 [ApplySceneViewportRenderPlan](../SceneViewportRenderPlan/ApplySceneViewportRenderPlan.md) +6. 调用 `SceneRenderer::Render(requests)` +7. 成功后调用 [MarkSceneViewportRenderSuccess](MarkSceneViewportRenderSuccess.md) + +其中本头文件承担的关键细节包括: + +- 失败文案与清屏色如何选择 +- request 的基础 object-id / post-pass 接线如何处理 +- 成功后资源状态如何回写 + +### Game View 路径 + +`ViewportHostService::RenderGameViewportEntry(...)` 更短一些: + +1. 检查活动场景 +2. 检查场景里是否有相机 +3. 直接调用 `SceneRenderer::Render(*scene, nullptr, ...)` +4. 成功后调用 [MarkGameViewportRenderSuccess](MarkGameViewportRenderSuccess.md) + +它不经过 `SceneViewportRenderPlan`,因为 Game View 不承担 Scene View 那套 editor overlay / selection outline 工作流。 + +## 当前实现要点 + +按 `ViewportHostRenderFlowUtils.h` 与 `tests/Editor/test_viewport_render_flow_utils.cpp` 当前实现: + +- `ViewportRenderFallbackPolicy` 默认不会清屏,但会默认让 object-id 帧失效。 +- `BuildViewportRenderTargetUnavailablePolicy()` 只给出文案,不执行清屏策略。 +- Scene / Game 失败策略都会要求清屏,但使用不同颜色区分“空场景”和“异常失败”。 +- `SceneRendererFailed` 的 Scene View 策略会使用 `setStatusIfEmpty = true`,以保留更具体的 warning。 +- `BuildSceneViewportGridPassData(...)` 当前只是字段复制层。 +- `BuildSceneViewportSelectionOutlineStyle(...)` 当前固定返回橙色 `2px` 轮廓。 +- `ApplySceneViewportRenderRequestSetup(...)` 会先清空 request 中旧的 pass / object-id 设置,再按条件重新挂接。 +- `MarkSceneViewportRenderSuccess(...)` 会同时更新颜色状态、object-id 状态和 object-id 帧有效标记。 +- `MarkGameViewportRenderSuccess(...)` 则只更新颜色状态,并明确让 object-id 帧无效。 + +## 设计说明 + +### 为什么编辑器视口不能只靠一个 `Render()` 返回值 + +在编辑器里,“画面没出来”远远不是全部问题。用户更关心: + +- 现在是没场景,还是没相机 +- 是 Scene View 自己缺前置条件,还是 renderer 真的失败了 +- object-id 还能不能继续做拾取 + +这也是为什么这里把失败反馈拆成“文案、清屏、object-id 帧有效性”三个维度,而不是用一个布尔值糊过去。 + +### 为什么 `SceneRendererFailed` 要保留已有 warning + +Scene View 在构建 render plan 时,可能已经得到了更精确但非致命的 warning,例如 object-id shader view 缺失。 + +如果后面 renderer 又失败了,直接把状态覆盖成 `Scene renderer failed`,用户就会失去更可行动的排查线索。`setStatusIfEmpty` 的设计,正是为了避免这种“后来的通用错误吃掉先来的具体 warning”。 + +### 为什么 object-id 要有显式失效标记 + +编辑器拾取系统最大的风险之一不是没有纹理,而是继续使用一张还存在、但其实已经过期的 object-id 结果。 + +因此这里专门把“资源还在”和“这帧结果是否有效”拆成两个概念: + +- 资源可以复用 +- 但有效性必须按本帧执行结果重置 + +这是一种非常典型的实时编辑器设计,能显著减少跨帧状态污染。 + +## 测试锚点 + +当前这组 helper 至少有以下直接测试覆盖: + +- `BuildFailurePoliciesExposeExpectedStatusAndClearBehavior` +- `ApplyViewportFailureStatusRespectsSetIfEmptyBehavior` +- `BuildSceneViewportGridPassDataCopiesSceneCameraState` +- `BuildSceneViewportSelectionOutlineStyleAppliesSceneDefaults` +- `ApplySceneRenderRequestSetupAttachesOptionalPassesAndObjectIdSurface` +- `ApplySceneRenderRequestSetupSkipsUnavailableOptionalAttachments` +- `MarkSceneRenderSuccessMovesTargetsToShaderResourceState` +- `MarkGameRenderSuccessClearsObjectIdFrameAndUpdatesColorState` + +## 当前边界 + +- 这里不负责 Scene View render plan 的高层组装;那部分已经移动到 [SceneViewportRenderPlan](../SceneViewportRenderPlan/SceneViewportRenderPlan.md)。 +- 这里不创建实际 pass,只创建 pass 所需的少量数据与样式,或负责 request 接线。 +- 当前 selection outline 样式仍是硬编码默认值,不是可主题化配置系统。 + +## 相关文档 + +- [Viewport](../Viewport.md) +- [ViewportHostService](../ViewportHostService/ViewportHostService.md) +- [ViewportHostRenderTargets](../ViewportHostRenderTargets/ViewportHostRenderTargets.md) +- [SceneViewportRenderPlan](../SceneViewportRenderPlan/SceneViewportRenderPlan.md) +- [SceneViewportEditorOverlayData](../SceneViewportEditorOverlayData/SceneViewportEditorOverlayData.md) +- [CameraRenderRequest](../../../Rendering/CameraRenderRequest/CameraRenderRequest.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ViewportRenderFallbackPolicy.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ViewportRenderFallbackPolicy.md new file mode 100644 index 00000000..84afe1d2 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderFlowUtils/ViewportRenderFallbackPolicy.md @@ -0,0 +1,81 @@ +# ViewportRenderFallbackPolicy + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/ViewportHostRenderFlowUtils.h` + +## 定义 + +```cpp +struct ViewportRenderFallbackPolicy { + const char* statusText = nullptr; + Math::Color clearColor = Math::Color::Black(); + bool shouldClear = false; + bool setStatusIfEmpty = false; + bool invalidateObjectIdFrame = true; +}; +``` + +## 作用 + +把“视口这次失败以后应该怎样回退”收拢成一个明确的数据结构,供 `ViewportHostService::ApplyViewportRenderFailure(...)` 统一消费。 + +它解决的不是单一的清屏问题,而是一次编辑器视口失败处理里经常同时出现的三件事: + +- 状态栏应该显示什么文字。 +- 是否要清屏,以及清成什么颜色。 +- 是否要让上一帧 object-id 结果失效。 + +## 字段语义 + +| 字段 | 当前默认值 | 说明 | +|------|------|------| +| `statusText` | `nullptr` | 失败文案;为空时代表“不改状态文字”。 | +| `clearColor` | `Math::Color::Black()` | 当 `shouldClear == true` 时使用的清屏颜色。 | +| `shouldClear` | `false` | 是否要主动清理颜色 / 深度缓冲。 | +| `setStatusIfEmpty` | `false` | `true` 时仅在当前状态文字为空时写入文案。 | +| `invalidateObjectIdFrame` | `true` | 是否让当前 object-id 帧标记失效,防止后续拾取读到陈旧数据。 | + +## 当前实现行为 + +按 `ViewportHostRenderFlowUtils.h` 当前实现: + +- 这是所有视口失败策略 builder 的统一返回类型。 +- `BuildViewportRenderTargetUnavailablePolicy()` 只写文案,不清屏,保留默认的 `invalidateObjectIdFrame = true`。 +- `BuildSceneViewportRenderFailurePolicy(...)` 和 `BuildGameViewportRenderFailurePolicy(...)` 都会把 `shouldClear` 设为 `true`。 +- `SceneRendererFailed` 这一类 Scene View 失败会利用 `setStatusIfEmpty = true` 保留更早写入的、更具体的警告文案。 + +## 真实使用位置 + +- `ViewportHostService::ApplyViewportRenderFailure(...)` 会按该结构决定: + - 是否调用 `ApplyViewportFailureStatus(...)` + - 是否调用 `InvalidateViewportObjectIdFrame(...)` + - 是否调用 `ClearViewport(...)` +- `RenderViewportEntry(...)` 在 render target 缺失时,直接使用 [BuildViewportRenderTargetUnavailablePolicy](BuildViewportRenderTargetUnavailablePolicy.md)。 +- `RenderSceneViewportEntry(...)` / `RenderGameViewportEntry(...)` 分别通过 Scene / Game 失败枚举生成策略。 + +## 设计说明 + +把失败处理先表达成“策略对象”,再交给 service 执行,是编辑器渲染链里很有价值的拆分。 + +这样做的好处是: + +- 失败原因和失败动作解耦,便于测试。 +- Scene View 与 Game View 可以共享一套落地逻辑,但保留各自的失败语义。 +- 后续如果要增加更多 editor 级反馈,例如 warning icon、overlay banner、日志等级,也有明确扩展点,而不是继续往渲染主流程里堆 if/else。 + +## 测试锚点 + +- `BuildFailurePoliciesExposeExpectedStatusAndClearBehavior` +- `ApplyViewportFailureStatusRespectsSetIfEmptyBehavior` + +## 相关文档 + +- [ViewportHostRenderFlowUtils](ViewportHostRenderFlowUtils.md) +- [ApplyViewportFailureStatus](ApplyViewportFailureStatus.md) +- [BuildViewportRenderTargetUnavailablePolicy](BuildViewportRenderTargetUnavailablePolicy.md) +- [BuildSceneViewportRenderFailurePolicy](BuildSceneViewportRenderFailurePolicy.md) +- [BuildGameViewportRenderFailurePolicy](BuildGameViewportRenderFailurePolicy.md) +- [ViewportHostService](../ViewportHostService/ViewportHostService.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/BuildViewportColorSurface.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/BuildViewportColorSurface.md new file mode 100644 index 00000000..335e5762 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/BuildViewportColorSurface.md @@ -0,0 +1,35 @@ +# BuildViewportColorSurface + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/ViewportHostRenderTargets.h` + +## 签名 + +```cpp +Rendering::RenderSurface BuildViewportColorSurface(const ViewportRenderTargets& targets); +``` + +## 作用 + +基于当前颜色视图、深度视图和颜色资源状态构造颜色渲染表面。 + +## 当前实现行为 + +- 当前直接调用 [BuildViewportRenderSurface](../ViewportHostSurfaceUtils/BuildViewportRenderSurface.md)。 +- 传入的附件与状态为: + - `targets.colorView` + - `targets.depthView` + - `targets.colorState` +- `colorStateAfter` 仍沿用底层 helper 的默认值 `PixelShaderResource`。 + +## 测试覆盖 + +`tests/Editor/test_viewport_render_targets.cpp` 当前验证了它会复用颜色附件、深度附件和颜色状态。 + +## 相关文档 + +- [ViewportRenderTargets](ViewportRenderTargets.md) +- [BuildViewportObjectIdSurface](BuildViewportObjectIdSurface.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/BuildViewportObjectIdSurface.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/BuildViewportObjectIdSurface.md new file mode 100644 index 00000000..a89def15 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/BuildViewportObjectIdSurface.md @@ -0,0 +1,36 @@ +# BuildViewportObjectIdSurface + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/ViewportHostRenderTargets.h` + +## 签名 + +```cpp +Rendering::RenderSurface BuildViewportObjectIdSurface(const ViewportRenderTargets& targets); +``` + +## 作用 + +基于当前 object-id 视图、深度视图和 object-id 资源状态构造 object-id 渲染表面。 + +## 当前实现行为 + +- 当前直接调用 [BuildViewportRenderSurface](../ViewportHostSurfaceUtils/BuildViewportRenderSurface.md)。 +- 传入的附件与状态为: + - `targets.objectIdView` + - `targets.depthView` + - `targets.objectIdState` +- `colorStateAfter` 同样沿用底层 helper 的默认值 `PixelShaderResource`。 + +## 测试覆盖 + +`tests/Editor/test_viewport_render_targets.cpp` 当前验证了它会复用 object-id 附件、深度附件和 object-id 状态。 + +## 相关文档 + +- [ViewportRenderTargets](ViewportRenderTargets.md) +- [BuildViewportColorSurface](BuildViewportColorSurface.md) +- [ApplySceneViewportRenderRequestSetup](../ViewportHostRenderFlowUtils/ApplySceneViewportRenderRequestSetup.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/BuildViewportRenderTargetsReuseQuery.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/BuildViewportRenderTargetsReuseQuery.md new file mode 100644 index 00000000..df26403c --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/BuildViewportRenderTargetsReuseQuery.md @@ -0,0 +1,40 @@ +# BuildViewportRenderTargetsReuseQuery + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/ViewportHostRenderTargets.h` + +## 签名 + +```cpp +ViewportHostResourceReuseQuery BuildViewportRenderTargetsReuseQuery( + EditorViewportKind kind, + const ViewportRenderTargets& targets, + uint32_t requestedWidth, + uint32_t requestedHeight); +``` + +## 作用 + +把当前 `ViewportRenderTargets` 的资源占用状态转成可供复用判断使用的查询结构。 + +## 当前实现行为 + +- 会复制 `kind`、当前宽高和请求宽高。 +- 会把各资源指针是否为空映射到 `query.resources`: + - `colorTexture` / `colorView` + - `depthTexture` / `depthView` + - `objectIdTexture` / `objectIdView` / `objectIdShaderView` +- `hasTextureDescriptor` 当前通过 `targets.textureId != ImTextureID{}` 判断。 + +## 测试覆盖 + +`tests/Editor/test_viewport_render_targets.cpp` 当前验证了它会正确反映当前资源存在性。 + +## 相关文档 + +- [ViewportRenderTargets](ViewportRenderTargets.md) +- [ViewportHostResourceReuseQuery](../ViewportHostSurfaceUtils/ViewportHostResourceReuseQuery.md) +- [CanReuseViewportResources](../ViewportHostSurfaceUtils/CanReuseViewportResources.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/CreateViewportRenderTargets.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/CreateViewportRenderTargets.md new file mode 100644 index 00000000..a28f2a31 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/CreateViewportRenderTargets.md @@ -0,0 +1,46 @@ +# CreateViewportRenderTargets + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/ViewportHostRenderTargets.h` + +## 签名 + +```cpp +bool CreateViewportRenderTargets( + EditorViewportKind kind, + uint32_t width, + uint32_t height, + RHI::RHIDevice* device, + UI::ImGuiBackendBridge* backend, + ViewportRenderTargets& targets); +``` + +## 作用 + +为指定视口类型创建完整的 render target 资源包,并写回 `targets`。 + +## 当前实现行为 + +- 若 `width == 0`、`height == 0`、`device == nullptr` 或 `backend == nullptr`,直接返回 `false`。 +- 开始创建前会先调用 [DestroyViewportRenderTargets](DestroyViewportRenderTargets.md) 清理旧资源。 +- 然后依次创建: + - 颜色纹理与颜色 RTV + - 深度纹理与深度 DSV + - 若该视口类型需要,则再创建 object-id 纹理、RTV 与 SRV + - ImGui 颜色纹理描述符 +- 只要任一步失败,就会再次销毁当前半成品并返回 `false`。 +- 成功时会把 `colorState`、`objectIdState` 复位为 `Common`,并把 `hasValidObjectIdFrame` 置为 `false`。 + +## 当前边界 + +- 创建细节被封装在 `Detail::*` 内部 helper 中,不属于当前公开 API。 +- 当前没有独立单测直接覆盖成功路径,但 `ViewportHostService` 会依赖它创建实际视口资源。 + +## 相关文档 + +- [ViewportRenderTargets](ViewportRenderTargets.md) +- [DestroyViewportRenderTargets](DestroyViewportRenderTargets.md) +- [ViewportHostService](../ViewportHostService/ViewportHostService.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/DestroyViewportRenderTargets.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/DestroyViewportRenderTargets.md new file mode 100644 index 00000000..b137f5a0 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/DestroyViewportRenderTargets.md @@ -0,0 +1,41 @@ +# DestroyViewportRenderTargets + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/ViewportHostRenderTargets.h` + +## 签名 + +```cpp +void DestroyViewportRenderTargets( + UI::ImGuiBackendBridge* backend, + ViewportRenderTargets& targets); +``` + +## 作用 + +释放当前视口持有的 ImGui 描述符和全部 GPU 资源,并把目标结构重置为空状态。 + +## 当前实现行为 + +- 如果 `backend != nullptr` 且 `targets.imguiCpuHandle.ptr != 0`,会先释放 ImGui 纹理描述符。 +- 然后按顺序 `Shutdown + delete`: + - `objectIdView` + - `objectIdShaderView` + - `objectIdTexture` + - `depthView` + - `depthTexture` + - `colorView` + - `colorTexture` +- 最后会把尺寸、描述符句柄、`textureId`、资源状态和 `hasValidObjectIdFrame` 复位。 + +## 测试覆盖 + +`tests/Editor/test_viewport_render_targets.cpp` 当前验证了它会关闭并清空所有资源字段。 + +## 相关文档 + +- [ViewportRenderTargets](ViewportRenderTargets.md) +- [CreateViewportRenderTargets](CreateViewportRenderTargets.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/ViewportHostRenderTargets.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/ViewportHostRenderTargets.md new file mode 100644 index 00000000..71e37b7b --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/ViewportHostRenderTargets.md @@ -0,0 +1,58 @@ +# ViewportHostRenderTargets + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct + header-helper` + +**源文件**: `editor/src/Viewport/ViewportHostRenderTargets.h` + +**描述**: 定义 Editor 视口 render target 聚合结构,并负责颜色 / 深度 / object-id 目标与 ImGui 纹理描述符的创建销毁。 + +## 概述 + +`ViewportRenderTargets` 是 `ViewportHostService` 内部真正持有的视口资源包。当前一套资源可能包含: + +- 颜色纹理与 RTV。 +- 深度纹理与 DSV。 +- Scene 视口专用的 object-id 纹理、RTV 与 SRV。 +- ImGui 用于显示颜色纹理的描述符和 `ImTextureID`。 + +这个封装的价值是把“一个视口需要哪些 GPU 资源”收拢成稳定结构,而不是把很多裸指针散在 service 主类里。 + +## 公开类型与函数 + +| 成员 | 说明 | +|------|------| +| [ViewportRenderTargets](ViewportRenderTargets.md) | 当前视口资源聚合体。 | +| [BuildViewportRenderTargetsReuseQuery](BuildViewportRenderTargetsReuseQuery.md) | 把当前资源状态转成重用查询。 | +| [BuildViewportColorSurface](BuildViewportColorSurface.md) | 为颜色缓冲创建 `RenderSurface`。 | +| [BuildViewportObjectIdSurface](BuildViewportObjectIdSurface.md) | 为 object-id 缓冲创建 `RenderSurface`。 | +| [DestroyViewportRenderTargets](DestroyViewportRenderTargets.md) | 释放描述符与全部 GPU 资源。 | +| [CreateViewportRenderTargets](CreateViewportRenderTargets.md) | 依视口类型创建整套资源。 | + +## 当前实现行为 + +- `CreateViewportRenderTargets(...)` 会先销毁旧资源,再创建新资源。 +- 只有 `Scene` 视口会额外分配 object-id texture / RTV / SRV。 +- `CreateViewportTextureDescriptor(...)` 会通过 `ImGuiBackendBridge` 给颜色纹理创建可显示描述符。 +- 资源创建任一步失败都会整体回滚并返回 `false`。 + +## 设计说明 + +把 `object-id` 资源和普通颜色视口一起放进一个结构体,是很典型的编辑器视口做法。因为 Scene View 不是单纯“显示颜色图像”,它还承担选择、outline、高亮等工具语义,所以需要额外缓冲。 + +## 生命周期与所有权 + +- 这些资源由 [ViewportHostService](../ViewportHostService/ViewportHostService.md) 拥有。 +- `DestroyViewportRenderTargets(...)` 会负责释放 ImGui 描述符,并 `Shutdown + delete` 所有关联资源对象。 + +## 当前限制 + +- 当前没有跨视口共享 RT 池。 +- 当前 object-id 纹理格式固定为 `R8G8B8A8_UNorm`,依赖颜色编码对象 ID。 + +## 相关文档 + +- [ViewportHostSurfaceUtils](../ViewportHostSurfaceUtils/ViewportHostSurfaceUtils.md) +- [ViewportHostRenderFlowUtils](../ViewportHostRenderFlowUtils/ViewportHostRenderFlowUtils.md) +- [ViewportHostService](../ViewportHostService/ViewportHostService.md) diff --git a/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/ViewportRenderTargets.md b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/ViewportRenderTargets.md new file mode 100644 index 00000000..b5078174 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/ViewportHostRenderTargets/ViewportRenderTargets.md @@ -0,0 +1,39 @@ +# ViewportRenderTargets + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/ViewportHostRenderTargets.h` + +## 字段 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `width` | `uint32_t` | 当前 render target 宽度。 | +| `height` | `uint32_t` | 当前 render target 高度。 | +| `colorTexture` | `RHI::RHITexture*` | 颜色纹理。 | +| `colorView` | `RHI::RHIResourceView*` | 颜色 RTV。 | +| `depthTexture` | `RHI::RHITexture*` | 深度纹理。 | +| `depthView` | `RHI::RHIResourceView*` | 深度 DSV。 | +| `objectIdTexture` | `RHI::RHITexture*` | Scene 视口专用 object-id 纹理。 | +| `objectIdView` | `RHI::RHIResourceView*` | object-id RTV。 | +| `objectIdShaderView` | `RHI::RHIResourceView*` | object-id SRV。 | +| `imguiCpuHandle` | `D3D12_CPU_DESCRIPTOR_HANDLE` | ImGui 颜色纹理描述符 CPU 句柄。 | +| `imguiGpuHandle` | `D3D12_GPU_DESCRIPTOR_HANDLE` | ImGui 颜色纹理描述符 GPU 句柄。 | +| `textureId` | `ImTextureID` | ImGui 展示颜色纹理使用的纹理 id。 | +| `colorState` | `RHI::ResourceStates` | 当前颜色纹理状态。 | +| `objectIdState` | `RHI::ResourceStates` | 当前 object-id 纹理状态。 | +| `hasValidObjectIdFrame` | `bool` | 当前 object-id 帧是否可用于拾取 / outline。 | + +## 当前语义 + +- 这是一份由 [ViewportHostService](../ViewportHostService/ViewportHostService.md) 持有的完整视口资源包。 +- `objectId*` 字段主要服务于 Scene View;Game View 当前不会要求它们存在。 +- `colorState` 与 `objectIdState` 由渲染流程 helper 在成功渲染后回写。 + +## 相关文档 + +- [ViewportHostRenderTargets](ViewportHostRenderTargets.md) +- [BuildViewportRenderTargetsReuseQuery](BuildViewportRenderTargetsReuseQuery.md) +- [ViewportHostRenderFlowUtils](../ViewportHostRenderFlowUtils/ViewportHostRenderFlowUtils.md)