From c7eb9857cb600811eb3983ef64727382017ddba0 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Fri, 3 Apr 2026 15:53:16 +0800 Subject: [PATCH] docs: add scene viewport pass docs --- .../XCEngine/Editor/Viewport/Passes/Passes.md | 55 +++++++++++ .../CreateSceneViewportEditorOverlayPass.md | 51 ++++++++++ .../SceneViewportEditorOverlayPass/Render.md | 98 +++++++++++++++++++ .../SceneViewportEditorOverlayPass.md | 82 ++++++++++++++++ .../Shutdown.md | 56 +++++++++++ .../CreateSceneViewportGridPass.md | 51 ++++++++++ .../Passes/SceneViewportGridPass/Render.md | 46 +++++++++ .../SceneViewportGridPass.md | 57 +++++++++++ .../Passes/SceneViewportGridPass/Shutdown.md | 39 ++++++++ ...CreateSceneViewportSelectionOutlinePass.md | 55 +++++++++++ .../Render.md | 52 ++++++++++ .../SceneViewportSelectionOutlinePass.md | 68 +++++++++++++ .../Shutdown.md | 39 ++++++++ .../BuildSceneViewportShaderPath.md | 31 ++++++ .../GetSceneViewportInfiniteGridShaderPath.md | 31 ++++++ ...tSceneViewportObjectIdOutlineShaderPath.md | 31 ++++++ .../GetSceneViewportShaderRepoRootPath.md | 27 +++++ .../NormalizeSceneViewportShaderPath.md | 34 +++++++ .../SceneViewportShaderPaths.md | 55 +++++++++++ docs/api/XCEngine/Editor/Viewport/Viewport.md | 83 ++++++++++++++++ 20 files changed, 1041 insertions(+) create mode 100644 docs/api/XCEngine/Editor/Viewport/Passes/Passes.md create mode 100644 docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/CreateSceneViewportEditorOverlayPass.md create mode 100644 docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/Render.md create mode 100644 docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/SceneViewportEditorOverlayPass.md create mode 100644 docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/Shutdown.md create mode 100644 docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportGridPass/CreateSceneViewportGridPass.md create mode 100644 docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportGridPass/Render.md create mode 100644 docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportGridPass/SceneViewportGridPass.md create mode 100644 docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportGridPass/Shutdown.md create mode 100644 docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportSelectionOutlinePass/CreateSceneViewportSelectionOutlinePass.md create mode 100644 docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportSelectionOutlinePass/Render.md create mode 100644 docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportSelectionOutlinePass/SceneViewportSelectionOutlinePass.md create mode 100644 docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportSelectionOutlinePass/Shutdown.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/BuildSceneViewportShaderPath.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/GetSceneViewportInfiniteGridShaderPath.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/GetSceneViewportObjectIdOutlineShaderPath.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/GetSceneViewportShaderRepoRootPath.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/NormalizeSceneViewportShaderPath.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/SceneViewportShaderPaths.md create mode 100644 docs/api/XCEngine/Editor/Viewport/Viewport.md diff --git a/docs/api/XCEngine/Editor/Viewport/Passes/Passes.md b/docs/api/XCEngine/Editor/Viewport/Passes/Passes.md new file mode 100644 index 00000000..7987dcc9 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/Passes/Passes.md @@ -0,0 +1,55 @@ +# Passes + +**命名空间**: `XCEngine::Editor` + +**类型**: `submodule` + +**源目录**: `editor/src/Viewport/Passes/` + +**描述**: Scene View 专用 GPU pass 子模块,负责把 editor-owned 的网格、选中轮廓和世界 overlay 注入场景渲染请求。 + +## 概述 + +这个子目录当前包含三类 Scene View 专用 pass: + +- [SceneViewportGridPass](SceneViewportGridPass/SceneViewportGridPass.md) + - Editor 自己拥有的 post-scene 网格 pass,内部包装 [BuiltinInfiniteGridPass](../../../Rendering/Passes/BuiltinInfiniteGridPass/BuiltinInfiniteGridPass.md)。 +- [SceneViewportSelectionOutlinePass](SceneViewportSelectionOutlinePass/SceneViewportSelectionOutlinePass.md) + - Editor 自己拥有的 post-scene 选中轮廓 pass,内部包装 [BuiltinObjectIdOutlinePass](../../../Rendering/Passes/BuiltinObjectIdOutlinePass/BuiltinObjectIdOutlinePass.md)。 +- [SceneViewportEditorOverlayPass](SceneViewportEditorOverlayPass/SceneViewportEditorOverlayPass.md) + - Scene View 世界 overlay pass,负责画世界线段、图标 sprite 和屏幕三角形批次。 + +当前 Scene View 的 GPU 注入链路已经拆成两段: + +- `postScenePasses` + - `SceneViewportGridPass` + - `SceneViewportSelectionOutlinePass` +- `overlayPasses` + - `SceneViewportEditorOverlayPass` + +它们的职责都不是替代 `SceneViewPanel` 上的 ImGui 交互 overlay,而是把“真正属于 3D 场景空间或 Scene View 渲染阶段”的辅助内容接到 `SceneRenderer` 请求里。 + +这种分层很合理: + +- 需要在主场景之后、overlay 之前补一层编辑器效果的内容,放进 post-scene pass。 +- 需要和场景深度关系一致的世界 overlay,放进 overlay pass。 +- 需要响应鼠标命中、直接叠在 ImGui 纹理表面的 HUD / 前端控件,保留在 draw list。 + +## 当前实现限制 + +- 当前这些 pass 只在 `D3D12` 后端返回成功。 +- `SceneViewportGridPass` / `SceneViewportSelectionOutlinePass` 目前是 Editor 对 runtime builtin pass 的包装层,不是新的 runtime 公共语义。 +- overlay sprite 贴图来源仍是编辑器资源目录中的 PNG 文件,不是材质系统通用资源。 +- 这组 pass 由 [ViewportHostService](../ViewportHostService/ViewportHostService.md) 在 Scene View 渲染时按需注入,不是通用渲染管线公共 pass。 + +## 页面 + +- [SceneViewportGridPass](SceneViewportGridPass/SceneViewportGridPass.md) - `SceneViewportGridPass.h` +- [SceneViewportSelectionOutlinePass](SceneViewportSelectionOutlinePass/SceneViewportSelectionOutlinePass.md) - `SceneViewportSelectionOutlinePass.h` +- [SceneViewportEditorOverlayPass](SceneViewportEditorOverlayPass/SceneViewportEditorOverlayPass.md) - `SceneViewportEditorOverlayPass.h` + +## 相关文档 + +- [Viewport](../Viewport.md) +- [SceneViewportRenderPlan](../SceneViewportRenderPlan/SceneViewportRenderPlan.md) +- [SceneViewportOverlayBuilder](../SceneViewportOverlayBuilder/SceneViewportOverlayBuilder.md) diff --git a/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/CreateSceneViewportEditorOverlayPass.md b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/CreateSceneViewportEditorOverlayPass.md new file mode 100644 index 00000000..77b7faff --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/CreateSceneViewportEditorOverlayPass.md @@ -0,0 +1,51 @@ +# CreateSceneViewportEditorOverlayPass + +**命名空间**: `XCEngine::Editor` + +**类型**: `factory-function` + +**源文件**: `editor/src/Viewport/Passes/SceneViewportEditorOverlayPass.h` + +## 签名 + +```cpp +std::unique_ptr CreateSceneViewportEditorOverlayPass( + SceneViewportEditorOverlayPassRenderer& renderer, + const SceneViewportOverlayFrameData& frameData); +``` + +## 作用 + +创建一帧使用的 Scene View editor overlay pass,并把当前 `frameData` 绑定进去。 + +## 当前实现行为 + +当前工厂函数会返回一个内部 `SceneViewportEditorOverlayPass` 实例。这个 pass: + +- 持有对 `renderer` 的引用 +- 持有一份按值拷贝/移动进来的 `frameData` +- `GetName()` 固定返回 `"SceneViewportEditorOverlay"` +- `Execute(...)` 时调用 `renderer.Render(context.renderContext, context.surface, m_frameData)` + +因此它本质上是一个很薄的 `RenderPass` 适配层,用来把 Editor overlay renderer 接到 `SceneRenderer` 的 overlay pass 序列里。 + +## 所有权与生命周期 + +- 返回值拥有 pass 对象本身 +- `renderer` 不被 pass 拥有,调用方必须保证它在 pass 执行期间仍然有效 +- `frameData` 会进入 pass 对象内部,因此可以安全跨过当前调用栈,等到真正渲染时再消费 + +## 当前使用位置 + +典型调用方是 [ViewportHostService](../../ViewportHostService/ViewportHostService.md): + +1. 先合成 cached editor overlay 和 transient gizmo overlay +2. 再调用 `CreateSceneViewportEditorOverlayPass(...)` +3. 把结果挂进 `requests[0].overlayPasses` + +## 相关文档 + +- [SceneViewportEditorOverlayPass](SceneViewportEditorOverlayPass.md) +- [Render](Render.md) +- [Shutdown](Shutdown.md) +- [ViewportHostService](../../ViewportHostService/ViewportHostService.md) diff --git a/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/Render.md b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/Render.md new file mode 100644 index 00000000..8d07e12f --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/Render.md @@ -0,0 +1,98 @@ +# SceneViewportEditorOverlayPassRenderer::Render + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/Passes/SceneViewportEditorOverlayPass.h` + +## 签名 + +```cpp +bool Render( + const Rendering::RenderContext& renderContext, + const Rendering::RenderSurface& surface, + const SceneViewportOverlayFrameData& frameData); +``` + +## 作用 + +把当前帧 Scene View 世界 overlay 变成 GPU draw call,并绘制到给定 `RenderSurface` 的颜色目标上。 + +## 当前实现行为 + +### 1. 早退与初始化 + +- `frameData` 没有任何 overlay primitive 时,直接返回 `true` +- `renderContext` 无效或 `commandList` 为空时,也直接返回 `true` +- 真正开始绘制前会调用 `EnsureInitialized(renderContext)`,只支持 `D3D12` + +这意味着它把“当前帧没有 overlay 可画”视为成功路径,而不是异常。 + +### 2. 拆分三类批次 + +当前会先把 `frameData` 拆成三条绘制数据流: + +- `worldLines` +- `screenTriangles` +- `worldSprites` + +并且每一类都会再按 `SceneViewportOverlayDepthMode` 分成: + +- `DepthTested` +- `AlwaysOnTop` + +sprite 还会按 `sortDepth` 做 back-to-front 排序,以保证透明图标混合顺序稳定。 + +### 3. 准备动态 buffer + +按当前顶点总数,会分别调用: + +- `EnsureLineBufferCapacity(...)` +- `EnsureScreenTriangleBufferCapacity(...)` +- `EnsureSpriteBufferCapacity(...)` + +只要当前帧存在 sprite,还会调用 `EnsureIconTexturesLoaded()`,按需加载: + +- `camera_gizmo.png` +- `main_light_gizmo.png` + +### 4. 上传常量与切换 render target + +当前会把下面这些数据写入常量缓冲: + +- view-projection matrix +- viewport 宽高 +- 宽高倒数 + +然后把 Scene 视口颜色目标从 `surface.GetColorStateAfter()` 切到 `RenderTarget`,绘制结束后再切回原状态。 + +### 5. 依次绘制 line / sprite / screen triangle + +当前 draw 顺序是: + +1. line +2. sprite +3. screen triangle + +每一类内部都先画 `DepthTested`,再画 `AlwaysOnTop`,并切换到对应 pipeline state。 + +这让世界空间辅助线、图标和部分屏幕三角形 overlay 可以共享同一套 pass,但仍保留不同的深度语义。 + +## 返回值语义 + +- 资源初始化、buffer 准备、纹理加载和绘制都成功时,返回 `true` +- 初始化失败、buffer 扩容失败、icon 纹理加载失败或 render target 无效时,返回 `false` + +## 当前限制 + +- 只支持 `D3D12` +- sprite 贴图集合固定,不是开放式资源注册系统 +- 这条渲染路径只服务于 Editor Scene View overlay,不是通用 runtime pass + +## 相关文档 + +- [SceneViewportEditorOverlayPass](SceneViewportEditorOverlayPass.md) +- [Shutdown](Shutdown.md) +- [CreateSceneViewportEditorOverlayPass](CreateSceneViewportEditorOverlayPass.md) +- [SceneViewportEditorOverlayData](../../SceneViewportEditorOverlayData/SceneViewportEditorOverlayData.md) diff --git a/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/SceneViewportEditorOverlayPass.md b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/SceneViewportEditorOverlayPass.md new file mode 100644 index 00000000..a7dd5e06 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/SceneViewportEditorOverlayPass.md @@ -0,0 +1,82 @@ +# SceneViewportEditorOverlayPass + +**命名空间**: `XCEngine::Editor` + +**类型**: `renderer class + pass factory` + +**源文件**: `editor/src/Viewport/Passes/SceneViewportEditorOverlayPass.h` + +**描述**: Scene View 世界 overlay 的 GPU 渲染器与 pass 工厂,负责把 overlay 线段和图标批次画进场景颜色目标。 + +## 概述 + +`SceneViewportEditorOverlayPass` 这套代码解决的是“如何把 Scene View 的世界辅助元素真正画进 render target”。和 [SceneViewportOverlayRenderer](../../SceneViewportOverlayRenderer/SceneViewportOverlayRenderer.md) 不同,它不是 ImGui 前端 helper,而是 `RenderPass` 级别能力。 + +当前入口包括两部分: + +- `SceneViewportEditorOverlayPassRenderer` +- `CreateSceneViewportEditorOverlayPass(...)` + +## 生命周期与公开入口 + +- [Render](Render.md) + 把当前帧 `worldLines / screenTriangles / worldSprites` 转成 GPU draw call,并画进 Scene 视口颜色目标。 +- [Shutdown](Shutdown.md) + 释放 pipeline、descriptor set、动态图元 buffer 和内置 icon 纹理。 +- [CreateSceneViewportEditorOverlayPass](CreateSceneViewportEditorOverlayPass.md) + 生成一帧使用的 `RenderPass` 包装对象,把 `frameData` 绑定到当前 renderer。 + +## 当前实现行为 + +按 `SceneViewportEditorOverlayPass.cpp` 的实现: + +- `Render(...)` 只在有效 `RenderContext` 且后端类型为 `D3D12` 时可成功初始化。 +- 会分别维护: + - line pipeline + - sprite pipeline + - depth-tested / always-on-top 两套状态 +- 会按需扩容动态 line vertex buffer 与 sprite vertex buffer。 +- sprite 贴图当前只加载两张内置 PNG: + - `resources/Icons/camera_gizmo.png` + - `resources/Icons/main_light_gizmo.png` + +## 数据来源 + +这个 pass 消费的是 [SceneViewportOverlayFrameData](../../SceneViewportEditorOverlayData/SceneViewportEditorOverlayData.md): + +- `worldLines` -> 线段批次 +- `worldSprites` -> 图标 sprite 批次 + +通常由 [ViewportHostService](../../ViewportHostService/ViewportHostService.md) 在 Scene View 渲染请求里注入。 + +## 设计说明 + +为什么这部分要走 GPU pass,而不是和 gizmo 一样直接画在 ImGui 上? + +- 世界 overlay 需要和场景深度关系一致。 +- 这些内容本质上属于“场景的一部分辅助可视化”,不是纯 UI chrome。 +- 这样能更自然地支持 `DepthTested` 和 `AlwaysOnTop` 两种模式。 + +这是商业引擎常见的分工方式:真正属于 3D 空间的信息放在 render pass,编辑器控件壳子放在 UI 层。 + +## 生命周期与资源管理 + +- `SceneViewportEditorOverlayPassRenderer` 内部持有 pipeline、descriptor pool、sampler、buffer 和 icon texture 资源。 +- [Shutdown](Shutdown.md) / `DestroyResources()` 会释放这些 GPU 资源。 +- [CreateSceneViewportEditorOverlayPass](CreateSceneViewportEditorOverlayPass.md) 只是生成一帧使用的 `RenderPass` 包装对象,不拥有长期资源。 + +## 当前限制 + +- 当前只支持 `D3D12`。 +- sprite 贴图种类是固定内置集合,不支持开放式资源扩展。 +- 当前实现专门服务于 Editor Scene View,不是通用渲染管线 pass。 + +## 相关文档 + +- [Passes](../Passes.md) +- [Render](Render.md) +- [Shutdown](Shutdown.md) +- [CreateSceneViewportEditorOverlayPass](CreateSceneViewportEditorOverlayPass.md) +- [SceneViewportEditorOverlayData](../../SceneViewportEditorOverlayData/SceneViewportEditorOverlayData.md) +- [SceneViewportOverlayBuilder](../../SceneViewportOverlayBuilder/SceneViewportOverlayBuilder.md) +- [ViewportHostService](../../ViewportHostService/ViewportHostService.md) diff --git a/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/Shutdown.md b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/Shutdown.md new file mode 100644 index 00000000..4f2b7a62 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportEditorOverlayPass/Shutdown.md @@ -0,0 +1,56 @@ +# SceneViewportEditorOverlayPassRenderer::Shutdown + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/Passes/SceneViewportEditorOverlayPass.h` + +## 签名 + +```cpp +void Shutdown(); +``` + +## 作用 + +释放 `SceneViewportEditorOverlayPassRenderer` 持有的 GPU 资源,并把 renderer 复位到未初始化状态。 + +## 当前实现行为 + +`Shutdown()` 当前本身非常薄,只做一件事: + +```cpp +DestroyResources(); +``` + +而 `DestroyResources()` 会按资源类型依次释放: + +- line / screen-triangle / sprite 三类 vertex buffer 及 view +- camera / light 两张 overlay sprite 纹理、SRV 和 descriptor set +- depth-tested / always-on-top 两套 line、screen-triangle、sprite pipeline state +- sampler / constant / texture descriptor pool 与 descriptor set +- pipeline layout + +释放完成后还会把这些内部状态全部清空: + +- 各类指针置空 +- buffer capacity 置零 +- `m_device = nullptr` +- `m_backendType` 回到默认 `D3D12` + +## 设计含义 + +这个 API 的职责不是“结束一帧 pass”,而是“销毁长期缓存的 renderer 资源”。因此它通常出现在: + +- 编辑器关闭 +- 设备重建 +- 宿主 service shutdown + +而不是每帧调用。 + +## 相关文档 + +- [SceneViewportEditorOverlayPass](SceneViewportEditorOverlayPass.md) +- [Render](Render.md) +- [CreateSceneViewportEditorOverlayPass](CreateSceneViewportEditorOverlayPass.md) diff --git a/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportGridPass/CreateSceneViewportGridPass.md b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportGridPass/CreateSceneViewportGridPass.md new file mode 100644 index 00000000..0b7c431d --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportGridPass/CreateSceneViewportGridPass.md @@ -0,0 +1,51 @@ +# CreateSceneViewportGridPass + +**命名空间**: `XCEngine::Editor` + +**类型**: `factory-function` + +**源文件**: `editor/src/Viewport/Passes/SceneViewportGridPass.h` + +## 签名 + +```cpp +std::unique_ptr CreateSceneViewportGridPass( + SceneViewportGridPassRenderer& renderer, + const Rendering::Passes::InfiniteGridPassData& data); +``` + +## 作用 + +创建一个本帧使用的 Scene View 网格 `RenderPass`,把 `InfiniteGridPassData` 绑定到给定 renderer。 + +## 当前实现行为 + +当前工厂函数返回内部类 `SceneViewportGridPass` 的实例。这个 pass: + +- 持有对 `renderer` 的引用 +- 按值保存 `data` +- `GetName()` 固定返回 `"SceneViewportGrid"` +- `Execute(...)` 时调用 `renderer.Render(context.renderContext, context.surface, m_data)` + +因此它本质上是一个很薄的适配层,用来把 `SceneViewportGridPassRenderer` 接进 `RenderPassSequence`。 + +## 所有权与生命周期 + +- 返回值拥有 pass 对象本身 +- `renderer` 不被 pass 拥有,调用方必须保证 renderer 在 pass 执行前不会失效 +- `data` 会被复制进 pass 内部,因此可以安全跨过当前调用栈,等到真正渲染时再消费 + +## 当前使用位置 + +典型调用点是 [ViewportHostService](../../ViewportHostService/ViewportHostService.md): + +1. 先通过 `BuildSceneViewportGridPassData(...)` 组装 `InfiniteGridPassData` +2. 再经由 [SceneViewportRenderPlan](../../SceneViewportRenderPlan/SceneViewportRenderPlan.md) 的 `SceneViewportGridPassFactory` +3. 最终把结果挂进 `plan.postScenePasses` + +## 相关文档 + +- [SceneViewportGridPass](SceneViewportGridPass.md) +- [Render](Render.md) +- [Shutdown](Shutdown.md) +- [SceneViewportRenderPlan](../../SceneViewportRenderPlan/SceneViewportRenderPlan.md) diff --git a/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportGridPass/Render.md b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportGridPass/Render.md new file mode 100644 index 00000000..7fbe28e0 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportGridPass/Render.md @@ -0,0 +1,46 @@ +# SceneViewportGridPassRenderer::Render + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/Passes/SceneViewportGridPass.h` + +## 签名 + +```cpp +bool Render( + const Rendering::RenderContext& renderContext, + const Rendering::RenderSurface& surface, + const Rendering::Passes::InfiniteGridPassData& data); +``` + +## 作用 + +执行 Scene View 无限网格绘制,把一份 `InfiniteGridPassData` 转交给底层 `BuiltinInfiniteGridPass`。 + +## 当前实现行为 + +当前实现本身没有额外逻辑,函数体就是: + +```cpp +return m_gridPass.Render(renderContext, surface, data); +``` + +因此它的语义边界非常明确: + +- Editor 层不在这里修改网格参数 +- Editor 层不在这里补充 render target 或 clear 行为 +- 真正的初始化、shader 选择、绘制和失败条件都由 [BuiltinInfiniteGridPass](../../../../Rendering/Passes/BuiltinInfiniteGridPass/BuiltinInfiniteGridPass.md) 决定 + +## 返回值语义 + +- 当底层 `m_gridPass.Render(...)` 成功时,返回 `true` +- 当底层 pass 因上下文、资源或后端条件失败时,返回 `false` + +## 相关文档 + +- [SceneViewportGridPass](SceneViewportGridPass.md) +- [Shutdown](Shutdown.md) +- [CreateSceneViewportGridPass](CreateSceneViewportGridPass.md) +- [BuiltinInfiniteGridPass](../../../../Rendering/Passes/BuiltinInfiniteGridPass/BuiltinInfiniteGridPass.md) diff --git a/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportGridPass/SceneViewportGridPass.md b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportGridPass/SceneViewportGridPass.md new file mode 100644 index 00000000..00689330 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportGridPass/SceneViewportGridPass.md @@ -0,0 +1,57 @@ +# SceneViewportGridPass + +**命名空间**: `XCEngine::Editor` + +**类型**: `renderer class + pass factory` + +**源文件**: `editor/src/Viewport/Passes/SceneViewportGridPass.h` + +**描述**: Scene View 无限网格的 Editor 侧 `RenderPass` 适配层,把 Rendering 模块里的 `BuiltinInfiniteGridPass` 接到 viewport 的 `postScenePasses` 序列。 +## 概览 + +`SceneViewportGridPass.h` 没有重新实现网格算法,而是把 Runtime 侧现成的 [BuiltinInfiniteGridPass](../../../../Rendering/Passes/BuiltinInfiniteGridPass/BuiltinInfiniteGridPass.md) 包了一层 Editor 适配: + +- `SceneViewportGridPassRenderer` +- `CreateSceneViewportGridPass(...)` + +这样 `ViewportHostService` 在组装 [SceneViewportRenderPlan](../../SceneViewportRenderPlan/SceneViewportRenderPlan.md) 时,可以直接把 Scene View 相机姿态推导出的 `InfiniteGridPassData` 变成一个标准 `RenderPass`。 + +## 当前实现行为 + +按 `SceneViewportGridPass.cpp` 的当前实现: + +- `SceneViewportGridPassRenderer` 内部只持有一个 `BuiltinInfiniteGridPass m_gridPass` +- [Render](Render.md) 只是把 `renderContext`、`surface` 和 `InfiniteGridPassData` 原样转发给 `m_gridPass.Render(...)` +- [Shutdown](Shutdown.md) 只是转发到 `m_gridPass.Shutdown()` +- [CreateSceneViewportGridPass](CreateSceneViewportGridPass.md) 会创建一个内部 `SceneViewportGridPass` 对象: + - 持有对 `renderer` 的引用 + - 按值保存本帧的 `InfiniteGridPassData` + - `GetName()` 固定返回 `"SceneViewportGrid"` + +## 当前使用位置 + +- [SceneViewportRenderPlan](../../SceneViewportRenderPlan/SceneViewportRenderPlan.md) 里的 `SceneViewportGridPassFactory` 负责把 `BuildSceneViewportGridPassData(...)` 的结果转成 `RenderPass` +- [ViewportHostService](../../ViewportHostService/ViewportHostService.md) 当前把这个 factory 绑定到 `CreateSceneViewportGridPass(m_sceneViewportGridRenderer, data)` +- `tests/editor/test_viewport_render_flow_utils.cpp` 的 `BuildSceneViewportRenderPlanCollectsPostSceneAndOverlayPasses` 覆盖了 grid factory 被调用的路径 + +## 设计含义 + +把 `BuiltinInfiniteGridPass` 再包一层 Editor 侧 `RenderPass`,收益在于: + +- `SceneViewportRenderPlan` 可以只依赖抽象的 pass factory,而不用直接耦合具体 renderer 成员 +- 网格 pass 可以作为 Scene View 的普通 `postScenePass` 插到同一条计划链路里 +- 网格算法的实现仍然统一留在 Rendering 模块 + +## 当前限制 + +- 这个头文件本身只提供薄适配层,不暴露任何额外的 editor-specific 网格样式配置 +- 返回的 `RenderPass` 不拥有 `renderer`,调用方必须保证 renderer 在 pass 执行期间仍然有效 + +## 相关文档 + +- [Passes](../Passes.md) +- [Render](Render.md) +- [Shutdown](Shutdown.md) +- [CreateSceneViewportGridPass](CreateSceneViewportGridPass.md) +- [SceneViewportRenderPlan](../../SceneViewportRenderPlan/SceneViewportRenderPlan.md) +- [BuiltinInfiniteGridPass](../../../../Rendering/Passes/BuiltinInfiniteGridPass/BuiltinInfiniteGridPass.md) diff --git a/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportGridPass/Shutdown.md b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportGridPass/Shutdown.md new file mode 100644 index 00000000..2aeb3117 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportGridPass/Shutdown.md @@ -0,0 +1,39 @@ +# SceneViewportGridPassRenderer::Shutdown + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/Passes/SceneViewportGridPass.h` + +## 签名 + +```cpp +void Shutdown(); +``` + +## 作用 + +释放 `SceneViewportGridPassRenderer` 内部持有的底层无限网格 pass 资源。 + +## 当前实现行为 + +当前实现只有一行: + +```cpp +m_gridPass.Shutdown(); +``` + +也就是说,`SceneViewportGridPassRenderer` 自己并不管理额外的 Editor 私有资源;它只是把关闭动作透传给底层 `BuiltinInfiniteGridPass`。 + +## 使用时机 + +- [ViewportHostService](../../ViewportHostService/ViewportHostService.md) 在自身 `Shutdown()` 中调用它 +- 不需要每帧调用;它属于 renderer 生命周期收尾的一部分 + +## 相关文档 + +- [SceneViewportGridPass](SceneViewportGridPass.md) +- [Render](Render.md) +- [CreateSceneViewportGridPass](CreateSceneViewportGridPass.md) +- [BuiltinInfiniteGridPass](../../../../Rendering/Passes/BuiltinInfiniteGridPass/BuiltinInfiniteGridPass.md) diff --git a/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportSelectionOutlinePass/CreateSceneViewportSelectionOutlinePass.md b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportSelectionOutlinePass/CreateSceneViewportSelectionOutlinePass.md new file mode 100644 index 00000000..09bd050e --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportSelectionOutlinePass/CreateSceneViewportSelectionOutlinePass.md @@ -0,0 +1,55 @@ +# CreateSceneViewportSelectionOutlinePass + +**命名空间**: `XCEngine::Editor` + +**类型**: `factory-function` + +**源文件**: `editor/src/Viewport/Passes/SceneViewportSelectionOutlinePass.h` + +## 签名 + +```cpp +std::unique_ptr CreateSceneViewportSelectionOutlinePass( + SceneViewportSelectionOutlinePassRenderer& renderer, + RHI::RHIResourceView* objectIdTextureView, + const std::vector& selectedObjectIds, + const Rendering::Passes::ObjectIdOutlineStyle& style); +``` + +## 作用 + +创建一个本帧使用的 Scene View 选中轮廓 `RenderPass`,把 object-id 纹理、选中对象列表和样式绑定到给定 renderer。 + +## 当前实现行为 + +当前工厂函数返回内部类 `SceneViewportSelectionOutlinePass` 的实例。这个 pass: + +- 持有对 `renderer` 的引用 +- 保存 `objectIdTextureView` 指针 +- 按值复制 `selectedObjectIds` +- 按值复制 `style` +- `GetName()` 固定返回 `"SceneViewportSelectionOutline"` +- `Execute(...)` 时调用 `renderer.Render(...)` + +## 所有权与生命周期 + +- 返回值拥有 pass 对象本身 +- `renderer` 不被 pass 拥有,必须在 pass 执行期间保持有效 +- `objectIdTextureView` 只是借用指针,不会被 pass 接管所有权 +- `selectedObjectIds` 与 `style` 会复制进 pass 内部,因此可以跨过当前调用栈延后执行 + +## 当前使用位置 + +典型调用路径是: + +1. [BuildSceneViewportRenderPlan](../../SceneViewportRenderPlan/BuildSceneViewportRenderPlan.md) 检查 `selectedObjectIds` 非空 +2. 要求 `targets.objectIdShaderView` 可用,并用 `BuildSceneViewportSelectionOutlineStyle(...)` 生成样式 +3. 通过这个工厂把结果加入 `plan.postScenePasses` + +## 相关文档 + +- [SceneViewportSelectionOutlinePass](SceneViewportSelectionOutlinePass.md) +- [Render](Render.md) +- [Shutdown](Shutdown.md) +- [SceneViewportRenderPlan](../../SceneViewportRenderPlan/SceneViewportRenderPlan.md) +- [ObjectIdOutlineStyle](../../../../Rendering/Passes/ObjectIdOutlineStyle/ObjectIdOutlineStyle.md) diff --git a/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportSelectionOutlinePass/Render.md b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportSelectionOutlinePass/Render.md new file mode 100644 index 00000000..076c848b --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportSelectionOutlinePass/Render.md @@ -0,0 +1,52 @@ +# SceneViewportSelectionOutlinePassRenderer::Render + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/Passes/SceneViewportSelectionOutlinePass.h` + +## 签名 + +```cpp +bool Render( + const Rendering::RenderContext& renderContext, + const Rendering::RenderSurface& surface, + RHI::RHIResourceView* objectIdTextureView, + const std::vector& selectedObjectIds, + const Rendering::Passes::ObjectIdOutlineStyle& style); +``` + +## 作用 + +执行 Scene View 的选中轮廓绘制,把 object-id 纹理、选中对象列表和轮廓样式转交给底层 outline pass。 + +## 当前实现行为 + +当前实现没有额外包装逻辑,直接调用: + +```cpp +return m_outlinePass.Render( + renderContext, + surface, + objectIdTextureView, + selectedObjectIds, + style); +``` + +因此: + +- Editor 层不会在这里重新编码 object-id 或调整 outline 样式 +- 资源初始化、shader 选择、绘制与失败条件都由 [BuiltinObjectIdOutlinePass](../../../../Rendering/Passes/BuiltinObjectIdOutlinePass/BuiltinObjectIdOutlinePass.md) 决定 + +## 返回值语义 + +- 底层 outline pass 执行成功时返回 `true` +- 当 object-id 视图、上下文或后端条件不满足时,可能返回 `false` + +## 相关文档 + +- [SceneViewportSelectionOutlinePass](SceneViewportSelectionOutlinePass.md) +- [Shutdown](Shutdown.md) +- [CreateSceneViewportSelectionOutlinePass](CreateSceneViewportSelectionOutlinePass.md) +- [BuiltinObjectIdOutlinePass](../../../../Rendering/Passes/BuiltinObjectIdOutlinePass/BuiltinObjectIdOutlinePass.md) diff --git a/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportSelectionOutlinePass/SceneViewportSelectionOutlinePass.md b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportSelectionOutlinePass/SceneViewportSelectionOutlinePass.md new file mode 100644 index 00000000..035960fc --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportSelectionOutlinePass/SceneViewportSelectionOutlinePass.md @@ -0,0 +1,68 @@ +# SceneViewportSelectionOutlinePass + +**命名空间**: `XCEngine::Editor` + +**类型**: `renderer class + pass factory` + +**源文件**: `editor/src/Viewport/Passes/SceneViewportSelectionOutlinePass.h` + +**描述**: Scene View 选中轮廓的 Editor 侧 `RenderPass` 适配层,把基于 object-id 的 outline 绘制接入 viewport 的 `postScenePasses`。 +## 概览 + +`SceneViewportSelectionOutlinePass.h` 同样不是轮廓算法本体,而是对 [BuiltinObjectIdOutlinePass](../../../../Rendering/Passes/BuiltinObjectIdOutlinePass/BuiltinObjectIdOutlinePass.md) 的 Editor 封装: + +- `SceneViewportSelectionOutlinePassRenderer` +- `CreateSceneViewportSelectionOutlinePass(...)` + +它让 [SceneViewportRenderPlan](../../SceneViewportRenderPlan/SceneViewportRenderPlan.md) 可以把: + +- `objectIdTextureView` +- `selectedObjectIds` +- `ObjectIdOutlineStyle` + +组装成一个标准 `RenderPass`,随后插到 Scene View 的主场景绘制之后执行。 + +## 当前实现行为 + +按 `SceneViewportSelectionOutlinePass.cpp` 的当前实现: + +- renderer 内部只持有一个 `BuiltinObjectIdOutlinePass m_outlinePass` +- [Render](Render.md) 原样转发 `renderContext`、`surface`、`objectIdTextureView`、`selectedObjectIds` 与 `style` +- [Shutdown](Shutdown.md) 只调用 `m_outlinePass.Shutdown()` +- [CreateSceneViewportSelectionOutlinePass](CreateSceneViewportSelectionOutlinePass.md) 会创建内部 `SceneViewportSelectionOutlinePass`: + - 持有对 `renderer` 的引用 + - 保存 `objectIdTextureView` 指针 + - 按值保存 `selectedObjectIds` 与 `style` + - `GetName()` 固定返回 `"SceneViewportSelectionOutline"` + +## 当前使用位置 + +- [SceneViewportRenderPlan](../../SceneViewportRenderPlan/SceneViewportRenderPlan.md) 的 `SceneViewportSelectionOutlinePassFactory` 会在“有选中对象且 `objectIdShaderView` 可用”时创建这个 pass +- [ViewportHostService](../../ViewportHostService/ViewportHostService.md) 当前把该 factory 绑定到 `CreateSceneViewportSelectionOutlinePass(m_sceneViewportSelectionOutlineRenderer, ...)` +- `tests/editor/test_viewport_render_flow_utils.cpp` 覆盖了: + - 选中对象存在时 factory 被调用 + - `outlineWidthPixels == 2.0f` + - object-id 纹理缺失时返回警告文案 + +## 设计含义 + +这样拆层的好处是: + +- object-id 轮廓的真正 GPU 实现仍留在 Rendering 模块 +- Editor 侧只负责把 Scene View 的 object-id 纹理和选中列表接到正确的 pass 序列 +- `SceneViewportRenderPlan` 可以统一控制 grid、selection-outline 与 overlay 三条附加渲染链路 + +## 当前限制 + +- 返回的 pass 不拥有 `renderer`,也不拥有 `objectIdTextureView` 指向的资源 +- 选中轮廓能否成功执行,仍取决于 `objectIdTextureView` 生命周期与底层 `BuiltinObjectIdOutlinePass` 的约束 + +## 相关文档 + +- [Passes](../Passes.md) +- [Render](Render.md) +- [Shutdown](Shutdown.md) +- [CreateSceneViewportSelectionOutlinePass](CreateSceneViewportSelectionOutlinePass.md) +- [SceneViewportRenderPlan](../../SceneViewportRenderPlan/SceneViewportRenderPlan.md) +- [BuiltinObjectIdOutlinePass](../../../../Rendering/Passes/BuiltinObjectIdOutlinePass/BuiltinObjectIdOutlinePass.md) +- [ObjectIdOutlineStyle](../../../../Rendering/Passes/ObjectIdOutlineStyle/ObjectIdOutlineStyle.md) diff --git a/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportSelectionOutlinePass/Shutdown.md b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportSelectionOutlinePass/Shutdown.md new file mode 100644 index 00000000..b158c253 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/Passes/SceneViewportSelectionOutlinePass/Shutdown.md @@ -0,0 +1,39 @@ +# SceneViewportSelectionOutlinePassRenderer::Shutdown + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/Passes/SceneViewportSelectionOutlinePass.h` + +## 签名 + +```cpp +void Shutdown(); +``` + +## 作用 + +释放 `SceneViewportSelectionOutlinePassRenderer` 内部持有的底层 outline pass 资源。 + +## 当前实现行为 + +当前实现只有一行: + +```cpp +m_outlinePass.Shutdown(); +``` + +这说明 `SceneViewportSelectionOutlinePassRenderer` 自己并不维护额外的 editor-only GPU 状态;生命周期管理完全委托给 `BuiltinObjectIdOutlinePass`。 + +## 使用时机 + +- [ViewportHostService](../../ViewportHostService/ViewportHostService.md) 在整体 shutdown 路径中调用它 +- 不需要每帧调用;它属于 Scene View renderer 的长期资源回收步骤 + +## 相关文档 + +- [SceneViewportSelectionOutlinePass](SceneViewportSelectionOutlinePass.md) +- [Render](Render.md) +- [CreateSceneViewportSelectionOutlinePass](CreateSceneViewportSelectionOutlinePass.md) +- [BuiltinObjectIdOutlinePass](../../../../Rendering/Passes/BuiltinObjectIdOutlinePass/BuiltinObjectIdOutlinePass.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/BuildSceneViewportShaderPath.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/BuildSceneViewportShaderPath.md new file mode 100644 index 00000000..6b550f91 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/BuildSceneViewportShaderPath.md @@ -0,0 +1,31 @@ +# Detail::BuildSceneViewportShaderPath + +把 Scene View shader 相对路径拼成 repo 内绝对资源路径字符串。 + +```cpp +inline Containers::String BuildSceneViewportShaderPath(const std::filesystem::path& relativePath); +``` + +## 行为说明 + +当前实现会拼接: + +```text +{repo root}/editor/resources/shaders/scene-viewport/{relativePath} +``` + +然后再调用 [NormalizeSceneViewportShaderPath](NormalizeSceneViewportShaderPath.md) 输出规范化结果。 + +## 参数 + +- `relativePath` - `scene-viewport` 目录下的相对 shader 路径。 + +## 返回值 + +- `Containers::String` - 规范化后的完整资源路径。 + +## 相关文档 + +- [SceneViewportShaderPaths](SceneViewportShaderPaths.md) +- [GetSceneViewportShaderRepoRootPath](GetSceneViewportShaderRepoRootPath.md) +- [NormalizeSceneViewportShaderPath](NormalizeSceneViewportShaderPath.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/GetSceneViewportInfiniteGridShaderPath.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/GetSceneViewportInfiniteGridShaderPath.md new file mode 100644 index 00000000..0a105a6e --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/GetSceneViewportInfiniteGridShaderPath.md @@ -0,0 +1,31 @@ +# GetSceneViewportInfiniteGridShaderPath + +返回 Scene View 无限网格 shader 的资源路径。 + +```cpp +inline Containers::String GetSceneViewportInfiniteGridShaderPath(); +``` + +## 行为说明 + +当前实现把相对路径: + +```text +infinite-grid/infinite-grid.shader +``` + +交给 [BuildSceneViewportShaderPath](BuildSceneViewportShaderPath.md),最终得到 repo 内 `editor/resources/shaders/scene-viewport/infinite-grid/infinite-grid.shader` 的规范化字符串路径。 + +## 当前使用位置 + +- `SceneViewportGridPassRenderer` 构造时把这个路径交给 Runtime 侧 `BuiltinInfiniteGridPass` + +## 返回值 + +- `Containers::String` - 无限网格 shader 路径。 + +## 相关文档 + +- [SceneViewportShaderPaths](SceneViewportShaderPaths.md) +- [BuildSceneViewportShaderPath](BuildSceneViewportShaderPath.md) +- [SceneViewportGridPass](../Passes/SceneViewportGridPass/SceneViewportGridPass.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/GetSceneViewportObjectIdOutlineShaderPath.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/GetSceneViewportObjectIdOutlineShaderPath.md new file mode 100644 index 00000000..74f90026 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/GetSceneViewportObjectIdOutlineShaderPath.md @@ -0,0 +1,31 @@ +# GetSceneViewportObjectIdOutlineShaderPath + +返回 Scene View object-id outline shader 的资源路径。 + +```cpp +inline Containers::String GetSceneViewportObjectIdOutlineShaderPath(); +``` + +## 行为说明 + +当前实现把相对路径: + +```text +object-id-outline/object-id-outline.shader +``` + +交给 [BuildSceneViewportShaderPath](BuildSceneViewportShaderPath.md),最终得到 repo 内 `editor/resources/shaders/scene-viewport/object-id-outline/object-id-outline.shader` 的规范化字符串路径。 + +## 当前使用位置 + +- `SceneViewportSelectionOutlinePassRenderer` 构造时把这个路径交给 Runtime 侧 `BuiltinObjectIdOutlinePass` + +## 返回值 + +- `Containers::String` - object-id outline shader 路径。 + +## 相关文档 + +- [SceneViewportShaderPaths](SceneViewportShaderPaths.md) +- [BuildSceneViewportShaderPath](BuildSceneViewportShaderPath.md) +- [SceneViewportSelectionOutlinePass](../Passes/SceneViewportSelectionOutlinePass/SceneViewportSelectionOutlinePass.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/GetSceneViewportShaderRepoRootPath.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/GetSceneViewportShaderRepoRootPath.md new file mode 100644 index 00000000..87808fe4 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/GetSceneViewportShaderRepoRootPath.md @@ -0,0 +1,27 @@ +# Detail::GetSceneViewportShaderRepoRootPath + +返回当前 Scene View shader 路径拼接所使用的 repo root。 + +```cpp +inline std::filesystem::path GetSceneViewportShaderRepoRootPath(); +``` + +## 行为说明 + +当前实现有两条路径: + +- 如果定义了 `XCENGINE_EDITOR_REPO_ROOT` + - 直接把这个编译时宏转成 `std::filesystem::path` +- 否则 + - 以当前头文件 `__FILE__` 为起点,连续 `parent_path()` 三次回退到 repo root + +这让编辑器既可以在已知 repo root 的构建环境下直接使用固定路径,也可以在本地源码树里按相对位置回推。 + +## 返回值 + +- `std::filesystem::path` - 当前推导出的 repo root。 + +## 相关文档 + +- [SceneViewportShaderPaths](SceneViewportShaderPaths.md) +- [BuildSceneViewportShaderPath](BuildSceneViewportShaderPath.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/NormalizeSceneViewportShaderPath.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/NormalizeSceneViewportShaderPath.md new file mode 100644 index 00000000..a67ee974 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/NormalizeSceneViewportShaderPath.md @@ -0,0 +1,34 @@ +# Detail::NormalizeSceneViewportShaderPath + +把 `std::filesystem::path` 规范化并转成 `Containers::String`。 + +```cpp +inline Containers::String NormalizeSceneViewportShaderPath(const std::filesystem::path& path); +``` + +## 行为说明 + +当前实现等价于: + +```cpp +return Containers::String(path.lexically_normal().generic_string().c_str()); +``` + +这意味着: + +- 会先做 `lexically_normal()` +- 输出统一使用 `/` 分隔的 generic path +- 返回类型是 Editor / Rendering 侧常用的 `Containers::String` + +## 参数 + +- `path` - 待规范化的文件系统路径。 + +## 返回值 + +- `Containers::String` - 规范化后的字符串路径。 + +## 相关文档 + +- [SceneViewportShaderPaths](SceneViewportShaderPaths.md) +- [BuildSceneViewportShaderPath](BuildSceneViewportShaderPath.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/SceneViewportShaderPaths.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/SceneViewportShaderPaths.md new file mode 100644 index 00000000..45819b06 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportShaderPaths/SceneViewportShaderPaths.md @@ -0,0 +1,55 @@ +# SceneViewportShaderPaths + +**命名空间**: `XCEngine::Editor` + +**类型**: `inline helper header` + +**源文件**: `editor/src/Viewport/SceneViewportShaderPaths.h` + +**描述**: 为 Scene View 的 editor-owned GPU pass 生成 repo 内 shader 资源路径。 + +## 概览 + +`SceneViewportShaderPaths.h` 是一个纯 inline helper 头文件。它不负责加载 shader,也不触碰 `AssetDatabase`;当前职责只是把 repo 根目录和 Scene View shader 相对路径拼成稳定的 `Containers::String`。 + +这组 helper 当前服务于两条 editor-owned pass 路径: + +- [SceneViewportGridPass](../Passes/SceneViewportGridPass/SceneViewportGridPass.md) +- [SceneViewportSelectionOutlinePass](../Passes/SceneViewportSelectionOutlinePass/SceneViewportSelectionOutlinePass.md) + +## 当前实现行为 + +- [GetSceneViewportShaderRepoRootPath](GetSceneViewportShaderRepoRootPath.md) + - 优先使用编译宏 `XCENGINE_EDITOR_REPO_ROOT` + - 否则回退到基于 `__FILE__` 的相对路径推导 +- [BuildSceneViewportShaderPath](BuildSceneViewportShaderPath.md) + - 会把 repo root、`editor/resources/shaders/scene-viewport/` 和传入相对路径拼接起来 +- [NormalizeSceneViewportShaderPath](NormalizeSceneViewportShaderPath.md) + - 把 `std::filesystem::path` 规范化成 `Containers::String` +- [GetSceneViewportInfiniteGridShaderPath](GetSceneViewportInfiniteGridShaderPath.md) + - 返回无限网格 shader 路径 +- [GetSceneViewportObjectIdOutlineShaderPath](GetSceneViewportObjectIdOutlineShaderPath.md) + - 返回 object-id outline shader 路径 + +## 当前使用位置 + +- `editor/src/Viewport/Passes/SceneViewportGridPass.cpp` + - `SceneViewportGridPassRenderer` 构造时调用 `GetSceneViewportInfiniteGridShaderPath()` +- `editor/src/Viewport/Passes/SceneViewportSelectionOutlinePass.cpp` + - `SceneViewportSelectionOutlinePassRenderer` 构造时调用 `GetSceneViewportObjectIdOutlineShaderPath()` + +## 当前限制 + +- 这里只负责拼路径,不验证目标文件是否存在 +- 路径策略当前写死在 repo 内 `editor/resources/shaders/scene-viewport/` +- Detail 命名空间下的 helper 也是 header 内直接暴露的 inline 实现,不是独立编译单元 + +## 相关文档 + +- [NormalizeSceneViewportShaderPath](NormalizeSceneViewportShaderPath.md) +- [GetSceneViewportShaderRepoRootPath](GetSceneViewportShaderRepoRootPath.md) +- [BuildSceneViewportShaderPath](BuildSceneViewportShaderPath.md) +- [GetSceneViewportInfiniteGridShaderPath](GetSceneViewportInfiniteGridShaderPath.md) +- [GetSceneViewportObjectIdOutlineShaderPath](GetSceneViewportObjectIdOutlineShaderPath.md) +- [SceneViewportGridPass](../Passes/SceneViewportGridPass/SceneViewportGridPass.md) +- [SceneViewportSelectionOutlinePass](../Passes/SceneViewportSelectionOutlinePass/SceneViewportSelectionOutlinePass.md) diff --git a/docs/api/XCEngine/Editor/Viewport/Viewport.md b/docs/api/XCEngine/Editor/Viewport/Viewport.md new file mode 100644 index 00000000..9557c978 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/Viewport.md @@ -0,0 +1,83 @@ +# Viewport + +**命名空间**: `XCEngine::Editor` + +**类型**: `module` + +**源目录**: `editor/src/Viewport/` + +**描述**: 编辑器视口基础设施模块,负责 Scene / Game 视口请求、隐藏编辑器相机、对象选择、overlay 构建与 gizmo 交互底层。 + +## 概述 + +`Viewport` 是当前 Editor 里最接近“场景视图内核”的一层。`SceneViewPanel` 和 `GameViewPanel` 都不直接管理渲染目标、场景相机请求或对象 ID 读回,而是通过这层完成: + +- 视口纹理请求与尺寸管理。 +- Scene View 专用编辑器相机控制。 +- Scene View 的对象 ID picking。 +- 场景图标、相机视锥、方向光辅助线等 overlay 数据构建。 +- Move / Rotate / Scale gizmo 的命中、拖拽和绘制数据生成。 +- Scene View GPU pass 注入。 + +从设计上看,这层相当于“Editor 视口宿主服务 + 交互 helper”的组合,而不是单一类。 + +## 设计要点 + +- `SceneViewPanel` 只负责 UI、快捷键和交互编排,真正的视口资源管理放在 [ViewportHostService](ViewportHostService/ViewportHostService.md)。 +- Scene View 不直接复用场景内相机,而是维护一台隐藏的编辑器相机,这和 Unity Scene View 的思路一致,能把编辑视角与游戏相机解耦。 +- 当前 Scene View 的可视化链路已经拆成三段: + - editor-owned post-scene pass: [SceneViewportGridPass](Passes/SceneViewportGridPass/SceneViewportGridPass.md) 与 [SceneViewportSelectionOutlinePass](Passes/SceneViewportSelectionOutlinePass/SceneViewportSelectionOutlinePass.md) + - GPU 世界 overlay pass: [SceneViewportEditorOverlayPass](Passes/SceneViewportEditorOverlayPass/SceneViewportEditorOverlayPass.md) + - ImGui 前端 HUD / 交互 overlay: [SceneViewportOverlayRenderer](SceneViewportOverlayRenderer/SceneViewportOverlayRenderer.md) +- 宿主服务内部还把 Scene View overlay 再拆成: + - 可缓存的基础 editor overlay + - hit test 用的 interaction overlay + - 渲染阶段追加的 transient gizmo overlay +- gizmo 的“可视几何构建”和“鼠标命中”当前已经拆成 [SceneViewportOverlayHandleBuilder](SceneViewportOverlayHandleBuilder/SceneViewportOverlayHandleBuilder.md) 与 [SceneViewportOverlayHitTester](SceneViewportOverlayHitTester/SceneViewportOverlayHitTester.md) 两层。 +- 当前 `SceneViewPanel` 的点击选取主路径是对象 ID 读回,不是 CPU mesh 射线拾取;后者目前保留在 [SceneViewportPicker](SceneViewportPicker/SceneViewportPicker.md) 里作为独立 helper。 + +## 当前实现边界 + +- `Viewport` 是 `editor/src` 下的 Editor 私有模块,不是 `engine/include/XCEngine/**` 那种 Runtime 公共 API。 +- 当前 Scene View 的 GPU pass 只在 `D3D12` 后端上真正可渲染。 +- `SceneViewportCameraController` 具备 orbit 输入能力,但当前 `SceneViewPanel` 主要驱动的是 look / pan / fly / focus selection。 + +## 目录结构 + +| 页面 | 说明 | +|------|------| +| [IViewportHostService](IViewportHostService/IViewportHostService.md) | Scene / Game 视口宿主服务抽象,以及共享输入/输出数据结构。 | +| [SceneViewportCameraController](SceneViewportCameraController/SceneViewportCameraController.md) | 隐藏编辑器相机的轨道/飞行控制器。 | +| [SceneViewportEditorOverlayData](SceneViewportEditorOverlayData/SceneViewportEditorOverlayData.md) | 世界 overlay 基元与帧缓存数据。 | +| [SceneViewportMath](SceneViewportMath/SceneViewportMath.md) | 视口投影、拖拽平面、屏幕方向等数学 helper。 | +| [SceneViewportMoveGizmo](SceneViewportMoveGizmo/SceneViewportMoveGizmo.md) | 位移 gizmo。 | +| [SceneViewportOrientationGizmo](SceneViewportOrientationGizmo/SceneViewportOrientationGizmo.md) | 右上角朝向立方体与点击对齐 helper。 | +| [SceneViewportOverlayHandleBuilder](SceneViewportOverlayHandleBuilder/SceneViewportOverlayHandleBuilder.md) | 把 gizmo draw data 转成屏幕三角形和 handle 记录。 | +| [SceneViewportOverlayHitTester](SceneViewportOverlayHitTester/SceneViewportOverlayHitTester.md) | 基于 handle 记录做鼠标命中选择。 | +| [SceneViewportOverlayBuilder](SceneViewportOverlayBuilder/SceneViewportOverlayBuilder.md) | 构建 Scene View 世界 overlay 帧数据。 | +| [SceneViewportOverlayRenderer](SceneViewportOverlayRenderer/SceneViewportOverlayRenderer.md) | 在 ImGui draw list 上绘制 gizmo 与前端 overlay。 | +| [SceneViewportRenderPlan](SceneViewportRenderPlan/SceneViewportRenderPlan.md) | Scene View 渲染前的 post-scene passes、overlay pass 与 clear-color override 计划对象。 | +| [SceneViewportShaderPaths](SceneViewportShaderPaths/SceneViewportShaderPaths.md) | Scene View 专用 shader 资源路径 helper。 | +| [SceneViewportPicker](SceneViewportPicker/SceneViewportPicker.md) | CPU 射线拾取 helper。 | +| [SceneViewportRotateGizmo](SceneViewportRotateGizmo/SceneViewportRotateGizmo.md) | 旋转 gizmo。 | +| [SceneViewportScaleGizmo](SceneViewportScaleGizmo/SceneViewportScaleGizmo.md) | 缩放 gizmo。 | +| [SceneViewportTransformGizmoFrameBuilder](SceneViewportTransformGizmoFrameBuilder/SceneViewportTransformGizmoFrameBuilder.md) | 组装每帧 transform gizmo 选择状态、pivot 和三类 gizmo context。 | +| [ViewportHostRenderFlowUtils](ViewportHostRenderFlowUtils/ViewportHostRenderFlowUtils.md) | Scene / Game 视口渲染流程辅助函数。 | +| [ViewportHostRenderTargets](ViewportHostRenderTargets/ViewportHostRenderTargets.md) | 视口颜色 / 深度 / object-id 目标创建与销毁。 | +| [ViewportHostService](ViewportHostService/ViewportHostService.md) | `IViewportHostService` 的当前实现。 | +| [ViewportHostSurfaceUtils](ViewportHostSurfaceUtils/ViewportHostSurfaceUtils.md) | render surface、重用判断和像素坐标工具。 | +| [ViewportObjectIdPicker](ViewportObjectIdPicker/ViewportObjectIdPicker.md) | object-id 读回与颜色解码 helper。 | +| [Passes](Passes/Passes.md) | Scene View editor-owned post-scene / overlay pass 子目录。 | + +## 与上层面板的关系 + +- [SceneViewPanel](../panels/SceneViewPanel/SceneViewPanel.md) 是当前 `Viewport` 模块最主要的调用方。 +- `SceneViewPanel` 通过 [ViewportPanelContent](../panels/ViewportPanelContent/ViewportPanelContent.md) 统一请求纹理并建立交互表面。 +- `GameViewPanel` 也会复用 `IViewportHostService::RequestViewport(...)` 这条链路,但不会进入 Scene gizmo / picking 流程。 + +## 相关文档 + +- [Editor](../Editor.md) +- [SceneViewPanel](../panels/SceneViewPanel/SceneViewPanel.md) +- [SceneView Interaction And Gizmo Model](../../../_guides/Editor/SceneView-Interaction-And-Gizmo-Model.md) +- [ViewportPanelContent](../panels/ViewportPanelContent/ViewportPanelContent.md)