docs: add scene viewport pass docs
This commit is contained in:
55
docs/api/XCEngine/Editor/Viewport/Passes/Passes.md
Normal file
55
docs/api/XCEngine/Editor/Viewport/Passes/Passes.md
Normal file
@@ -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)
|
||||
@@ -0,0 +1,51 @@
|
||||
# CreateSceneViewportEditorOverlayPass
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `factory-function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/Passes/SceneViewportEditorOverlayPass.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
std::unique_ptr<Rendering::RenderPass> 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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -0,0 +1,51 @@
|
||||
# CreateSceneViewportGridPass
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `factory-function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/Passes/SceneViewportGridPass.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
std::unique_ptr<Rendering::RenderPass> 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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -0,0 +1,55 @@
|
||||
# CreateSceneViewportSelectionOutlinePass
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `factory-function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/Passes/SceneViewportSelectionOutlinePass.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
std::unique_ptr<Rendering::RenderPass> CreateSceneViewportSelectionOutlinePass(
|
||||
SceneViewportSelectionOutlinePassRenderer& renderer,
|
||||
RHI::RHIResourceView* objectIdTextureView,
|
||||
const std::vector<uint64_t>& 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)
|
||||
@@ -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<uint64_t>& 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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
83
docs/api/XCEngine/Editor/Viewport/Viewport.md
Normal file
83
docs/api/XCEngine/Editor/Viewport/Viewport.md
Normal file
@@ -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)
|
||||
Reference in New Issue
Block a user