Compare commits
2 Commits
d4bec254d1
...
cb3d558aaa
| Author | SHA1 | Date | |
|---|---|---|---|
| cb3d558aaa | |||
| b0625a30bd |
@@ -54,7 +54,6 @@
|
||||
- [MeshRendererComponent](MeshRendererComponent/MeshRendererComponent.md) - `MeshRendererComponent.h`,材质槽和渲染附加参数。
|
||||
- [VolumeRendererComponent](VolumeRendererComponent/VolumeRendererComponent.md) - `VolumeRendererComponent.h`,体积资源、体积材质与阴影标志绑定。
|
||||
- [TransformComponent](TransformComponent/TransformComponent.md) - `TransformComponent.h`,局部/世界变换与层级矩阵。
|
||||
- [VolumeRendererComponent](VolumeRendererComponent/VolumeRendererComponent.md) - `VolumeRendererComponent.h`,体数据、体材质和阴影标记组件。
|
||||
|
||||
## 推荐阅读顺序
|
||||
|
||||
|
||||
@@ -6,107 +6,113 @@
|
||||
|
||||
**头文件**: `XCEngine/Components/VolumeRendererComponent.h`
|
||||
|
||||
**源文件**: `engine/src/Components/VolumeRendererComponent.cpp`
|
||||
|
||||
**描述**: 体积渲染组件,负责把 `VolumeField`、体积材质和少量阴影标志绑定到 `GameObject` 上,并在序列化/反序列化与 deferred load 场景中保持资源身份恢复。
|
||||
**描述**: 体积渲染组件,保存 `VolumeField` 与 `Material` 的运行时句柄、项目资源身份与序列化路径,并暴露阴影相关开关。
|
||||
|
||||
## 角色概述
|
||||
|
||||
`VolumeRendererComponent` 回答的问题是:
|
||||
`VolumeRendererComponent` 是当前场景里体积对象进入渲染链路的组件侧入口。它回答的是:
|
||||
|
||||
- 这个对象是否要作为体积参与渲染?
|
||||
- 它绑定的是哪一个 `VolumeField`?
|
||||
- 它使用哪一个 `Material`?
|
||||
- 体积对象当前的阴影开关是什么?
|
||||
- 这个 `GameObject` 当前绑定的是哪份体积资源?
|
||||
- 这个体积资源应当使用哪份材质参与 `BuiltinVolumetricPass`?
|
||||
- 反序列化后是立即同步加载,还是在 deferred scene load 模式下延迟到首次访问时异步兑现?
|
||||
|
||||
和 [MeshRendererComponent](../MeshRendererComponent/MeshRendererComponent.md) 类似,它同时承担“运行时资源句柄”和“可持久化资源身份”两层职责。
|
||||
按当前实现,它同时维护两组并行状态:
|
||||
|
||||
## 当前状态模型
|
||||
- `VolumeField`
|
||||
- 运行时 `ResourceHandle`
|
||||
- 路径缓存 `m_volumeFieldPath`
|
||||
- 项目资源身份 `m_volumeFieldRef`
|
||||
- deferred async load 挂起状态
|
||||
- `Material`
|
||||
- 运行时 `ResourceHandle`
|
||||
- 路径缓存 `m_materialPath`
|
||||
- 项目资源身份 `m_materialRef`
|
||||
- deferred async load 挂起状态
|
||||
|
||||
当前实现维护两组几乎对称的资源状态:
|
||||
## 当前实现语义
|
||||
|
||||
| 状态 | 作用 |
|
||||
### 资源绑定
|
||||
|
||||
- `SetVolumeFieldPath(...)` / `SetMaterialPath(...)`
|
||||
- 立即清空挂起异步状态
|
||||
- 同步调用 `ResourceManager::Load<T>(path)`
|
||||
- 尝试把路径回填成稳定的 `AssetRef`
|
||||
- `SetVolumeField(...)` / `SetMaterial(...)`
|
||||
- 从句柄反推当前路径
|
||||
- 如果路径可解析为项目资源,则同步回填 `AssetRef`
|
||||
- `ClearVolumeField()` / `ClearMaterial()`
|
||||
- 同时清空句柄、路径、`AssetRef` 与挂起异步状态
|
||||
|
||||
### 序列化与反序列化
|
||||
|
||||
当前序列化优先级是:
|
||||
|
||||
- 对有有效 `AssetRef` 的项目资源,优先写 `volumeRef=` / `materialRef=`
|
||||
- 只有在没有有效 `AssetRef` 且路径带虚拟 scheme 时,才额外写 `volumePath=` / `materialPath=`
|
||||
- 阴影标志始终写为 `castShadows=` 与 `receiveShadows=`
|
||||
|
||||
`Deserialize(...)` 的恢复顺序是:
|
||||
|
||||
1. 先重置当前绑定与阴影标志。
|
||||
2. 如果存在有效 `AssetRef`,优先按 `AssetRef` 恢复。
|
||||
3. 在 deferred scene load 模式下,优先只恢复可解析路径,不立刻加载资源。
|
||||
4. 只有虚拟路径在没有 `AssetRef` 时会被保留并作为恢复入口。
|
||||
|
||||
这意味着:
|
||||
|
||||
- 普通项目资源的正式持久化协议是 `AssetRef`
|
||||
- `test://`、`builtin://` 这类虚拟路径才长期依赖路径文本本身
|
||||
|
||||
### deferred async load
|
||||
|
||||
`GetVolumeField()` / `GetVolumeFieldHandle()` 与 `GetMaterial()` / `GetMaterialHandle()` 都带副作用:
|
||||
|
||||
- 如果当前只有路径没有已兑现句柄,会先触发 `EnsureDeferredAsync*LoadStarted()`
|
||||
- 如果异步结果已经完成,会在读取前调用 `ResolvePending*()` 收口结果
|
||||
|
||||
因此在 deferred scene load 模式下,组件常见的中间状态是:
|
||||
|
||||
- 路径与 `AssetRef` 已恢复
|
||||
- 运行时句柄仍为空
|
||||
- 首次读取句柄时才真正发起或收口异步加载
|
||||
|
||||
## 公开接口
|
||||
|
||||
| 接口 | 作用 |
|
||||
|------|------|
|
||||
| `m_volumeField` / `m_volumeFieldPath` / `m_volumeFieldRef` | 体积资源句柄、路径缓存与稳定 `AssetRef`。 |
|
||||
| `m_material` / `m_materialPath` / `m_materialRef` | 材质句柄、路径缓存与稳定 `AssetRef`。 |
|
||||
| `m_pendingVolumeLoad` / `m_pendingMaterialLoad` | deferred async load 的挂起结果。 |
|
||||
| `m_asyncVolumeLoadRequested` / `m_asyncMaterialLoadRequested` | 防止重复发起异步加载。 |
|
||||
| `m_castShadows` / `m_receiveShadows` | 阴影相关附加开关。 |
|
||||
| `GetVolumeField()` / `GetVolumeFieldHandle()` | 读取体积资源,并在需要时触发 deferred async load 收口 |
|
||||
| `GetVolumeFieldPath()` / `GetVolumeFieldAssetRef()` | 读取体积资源元数据,不直接暴露 GPU/渲染行为 |
|
||||
| `SetVolumeFieldPath(...)` / `SetVolumeField(...)` / `ClearVolumeField()` | 绑定或清空体积资源 |
|
||||
| `GetMaterial()` / `GetMaterialHandle()` | 读取材质,并在需要时触发 deferred async load 收口 |
|
||||
| `GetMaterialPath()` / `GetMaterialAssetRef()` | 读取材质元数据 |
|
||||
| `SetMaterialPath(...)` / `SetMaterial(...)` / `ClearMaterial()` | 绑定或清空材质 |
|
||||
| `GetCastShadows()` / `SetCastShadows(...)` | 控制组件层阴影投射标志 |
|
||||
| `GetReceiveShadows()` / `SetReceiveShadows(...)` | 控制组件层阴影接收标志 |
|
||||
| `Serialize(...)` / `Deserialize(...)` | 负责场景文本中的体积/材质引用恢复协议 |
|
||||
|
||||
## 绑定与恢复流程
|
||||
|
||||
### 1. 运行时按路径设置
|
||||
|
||||
- `SetVolumeFieldPath(...)` 会立即尝试 `ResourceManager::Load<VolumeField>(path)`。
|
||||
- `SetMaterialPath(...)` 会立即尝试 `ResourceManager::Load<Material>(path)`。
|
||||
- 两条路径都会额外调用 `TryGetAssetRef(...)`,尽量把项目路径回填成稳定资源身份。
|
||||
|
||||
### 2. 运行时按句柄设置
|
||||
|
||||
- `SetVolumeField(...)` 与 `SetMaterial(...)` 会从句柄反推出路径。
|
||||
- 若路径对应项目资产,也会同步尝试回填 `AssetRef`。
|
||||
|
||||
### 3. 序列化与反序列化
|
||||
|
||||
`Serialize()` 当前优先写:
|
||||
|
||||
- `volumeRef`
|
||||
- `materialRef`
|
||||
|
||||
只有在没有有效 `AssetRef` 且路径带 virtual scheme 时,才会保留:
|
||||
|
||||
- `volumePath`
|
||||
- `materialPath`
|
||||
|
||||
`Deserialize()` 当前会先清空旧状态,再恢复:
|
||||
|
||||
- 体积资源身份
|
||||
- 材质资源身份
|
||||
- `castShadows`
|
||||
- `receiveShadows`
|
||||
|
||||
若开启 deferred scene load,则会优先只恢复路径/身份,等首次访问句柄时再启动异步兑现。
|
||||
|
||||
## 与 deferred scene load 的关系
|
||||
|
||||
- `GetVolumeField()` / `GetVolumeFieldHandle()` 会触发:
|
||||
- `EnsureDeferredAsyncVolumeLoadStarted()`
|
||||
- `ResolvePendingVolumeField()`
|
||||
- `GetMaterial()` / `GetMaterialHandle()` 会触发:
|
||||
- `EnsureDeferredAsyncMaterialLoadStarted()`
|
||||
- `ResolvePendingMaterial()`
|
||||
|
||||
因此这几个 getter 不是纯只读访问器,而是带有“补发异步兑现”的副作用。
|
||||
|
||||
## 与渲染链路的关系
|
||||
|
||||
- `RenderSceneUtility` 当前会从对象上提取 `VolumeRendererComponent`,并构造 [VisibleVolumeItem](../../Rendering/FrameData/VisibleVolumeItem/VisibleVolumeItem.md)。
|
||||
- 后续 [BuiltinVolumetricPass](../../Rendering/Passes/BuiltinVolumetricPass/BuiltinVolumetricPass.md) 会消费这些可见体积项。
|
||||
- 这意味着“组件存在”不等于“这一帧一定有可绘制体积”:
|
||||
- 体积资源可能尚未兑现
|
||||
- 材质可能为空
|
||||
- deferred load 可能仍在挂起
|
||||
|
||||
## 测试与锚点
|
||||
## 测试与调用链
|
||||
|
||||
- `tests/Components/test_volume_renderer_component.cpp`
|
||||
- `SetResourcesCachesHandlesPathsAndFlags`
|
||||
- `SerializeAndDeserializePreservesVirtualPathsAndFlags`
|
||||
- `DeferredSceneDeserializeLoadsVolumeFieldAsyncByPath`
|
||||
- `tests/Rendering/unit/test_render_scene_extractor.cpp`
|
||||
- 覆盖体积对象被提取进渲染场景数据
|
||||
- `engine/src/Components/ComponentFactoryRegistry.cpp`
|
||||
- 当前把 `"VolumeRenderer"` 注册为内建组件类型
|
||||
- 覆盖句柄/路径缓存
|
||||
- 覆盖虚拟路径序列化
|
||||
- 覆盖 deferred scene load 下按路径异步恢复体积资源
|
||||
- `engine/src/Rendering/Extraction/RenderSceneUtility.cpp`
|
||||
- 当前通过本组件读取 `VolumeField` 与 `Material`,组装 `VisibleVolumeItem`
|
||||
- `editor/src/ComponentEditors/VolumeRendererComponentEditor.h`
|
||||
- 当前 Inspector 里的 Volume Renderer 面板直接调用本组件的路径与阴影接口
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 正式持久化协议优先是 `AssetRef`,不是普通项目路径。
|
||||
- 只有 virtual scheme 路径才会在没有有效 `AssetRef` 时稳定保留。
|
||||
- 当前组件只维护一个体积资源和一个材质,不涉及更复杂的多体积槽位模型。
|
||||
- 组件只负责 CPU 侧资源引用与场景序列化,不负责 GPU 上传。
|
||||
- 当前 `Get*Handle()` / `Get*()` 不是纯读取器,调用方要接受其会触发异步加载状态推进。
|
||||
- 没有有效 `AssetRef` 的普通项目路径不会被当成正式持久化协议长期保留。
|
||||
- 阴影标志当前在组件侧可读写可序列化,但具体是否在所有渲染路径都生效,要看上游提取与 pass 实现。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前模块](../Components.md)
|
||||
- [Components](../Components.md)
|
||||
- [VolumeField](../../Resources/Volume/VolumeField/VolumeField.md)
|
||||
- [Material](../../Resources/Material/Material/Material.md)
|
||||
- [VisibleVolumeItem](../../Rendering/FrameData/VisibleVolumeItem/VisibleVolumeItem.md)
|
||||
- [BuiltinVolumetricPass](../../Rendering/Passes/BuiltinVolumetricPass/BuiltinVolumetricPass.md)
|
||||
- [VolumeRendererComponentEditor](../../Editor/ComponentEditors/VolumeRendererComponentEditor/VolumeRendererComponentEditor.md)
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
| [AssetReferenceEditorUtils](AssetReferenceEditorUtils/AssetReferenceEditorUtils.md) | 资产引用属性行 helper。 |
|
||||
| [MeshFilterComponentEditor](MeshFilterComponentEditor/MeshFilterComponentEditor.md) | MeshFilter 组件 Inspector。 |
|
||||
| [MeshRendererComponentEditor](MeshRendererComponentEditor/MeshRendererComponentEditor.md) | MeshRenderer 组件 Inspector。 |
|
||||
| [VolumeRendererComponentEditor](VolumeRendererComponentEditor/VolumeRendererComponentEditor.md) | VolumeRenderer 组件 Inspector。 |
|
||||
| [ScriptComponentEditor](ScriptComponentEditor/ScriptComponentEditor.md) | Script 组件 Inspector 与脚本字段编辑入口。 |
|
||||
| [ScriptComponentEditorUtils](ScriptComponentEditorUtils/ScriptComponentEditorUtils.md) | 脚本组件编辑器辅助规则与格式化 helper。 |
|
||||
|
||||
@@ -54,9 +55,10 @@
|
||||
- `LightComponentEditor`
|
||||
- `MeshFilterComponentEditor`
|
||||
- `MeshRendererComponentEditor`
|
||||
- `VolumeRendererComponentEditor`
|
||||
- `ScriptComponentEditor`
|
||||
|
||||
这说明当前组件编辑器系统已经不再只覆盖基础三组件,而是已经承载渲染组件和脚本组件的 Inspector 逻辑。当前 canonical 树已经把渲染组件 editor、脚本组件 editor 和它们共用的资产引用 helper 都补齐了。
|
||||
这说明当前组件编辑器系统已经不再只覆盖基础三组件,而是已经承载 mesh、volume 与脚本组件的 Inspector 逻辑。当前 canonical 树已经把这些渲染组件 editor、脚本组件 editor 和它们共用的资产引用 helper 都补齐了。
|
||||
|
||||
## ScriptComponentEditor 的特殊性
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
# VolumeRendererComponentEditor
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/ComponentEditors/VolumeRendererComponentEditor.h`
|
||||
|
||||
**描述**: `VolumeRendererComponent` 的 Inspector editor,负责绘制体积资源引用、材质引用以及阴影开关。
|
||||
|
||||
## 概述
|
||||
|
||||
`VolumeRendererComponentEditor` 当前是内联定义在头文件里的轻量 editor,实现方式与其他 `ComponentEditor` 一致:
|
||||
|
||||
1. 由 `ComponentEditorRegistry` 注册
|
||||
2. 在 `InspectorPanel` 渲染组件 section 时被查到
|
||||
3. 直接通过 `UI::ApplyPropertyChange(...)` 把修改包进 undo 标签
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
### 资源引用编辑
|
||||
|
||||
- `Volume Field`
|
||||
- 通过 `ComponentEditorAssetUI::DrawAssetReferenceProperty(...)` 绘制
|
||||
- 当前接受扩展名 `.nvdb`
|
||||
- 清除时调用 `VolumeRendererComponent::ClearVolumeField()`
|
||||
- 赋值时调用 `SetVolumeFieldPath(...)`
|
||||
- `Material`
|
||||
- 同样使用 `DrawAssetReferenceProperty(...)`
|
||||
- 当前接受扩展名 `.mat`
|
||||
- 清除时调用 `ClearMaterial()`
|
||||
- 赋值时调用 `SetMaterialPath(...)`
|
||||
|
||||
### 布尔属性
|
||||
|
||||
- `Cast Shadows`
|
||||
- `Receive Shadows`
|
||||
|
||||
这两个布尔值都通过 `UI::DrawPropertyBool(...)` 与 `UI::ApplyPropertyChange(...)` 包装到统一 undo 标签:
|
||||
|
||||
- `Modify Volume Renderer`
|
||||
|
||||
### 添加与移除规则
|
||||
|
||||
- `CanAddTo(...)`
|
||||
- 只有目标 `GameObject` 还没有 `VolumeRendererComponent` 时才允许添加
|
||||
- `GetAddDisabledReason(...)`
|
||||
- `nullptr` `GameObject` 返回 `"Invalid"`
|
||||
- 已存在组件返回 `"Already Added"`
|
||||
- `CanRemove(...)`
|
||||
- 当前直接复用 `CanEdit(...)`
|
||||
|
||||
## 测试与调用链
|
||||
|
||||
- `editor/src/ComponentEditors/ComponentEditorRegistry.cpp`
|
||||
- 当前把本 editor 注册进全局 registry
|
||||
- `editor/src/panels/InspectorPanel.cpp`
|
||||
- 当前通过 registry 查找并渲染本 editor
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前没有独立单元测试,行为主要通过 registry 和 Inspector 实际渲染链验证。
|
||||
- 这是 editor-only UI 适配层,不保存状态;真正的数据写回都落在 `VolumeRendererComponent`。
|
||||
- 当前资源过滤只按扩展名限制,不负责进一步校验材质/体积内容是否合法。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [ComponentEditors](../ComponentEditors.md)
|
||||
- [ComponentEditorRegistry](../ComponentEditorRegistry/ComponentEditorRegistry.md)
|
||||
- [VolumeRendererComponent](../../../Components/VolumeRendererComponent/VolumeRendererComponent.md)
|
||||
- [InspectorPanel](../../panels/InspectorPanel/InspectorPanel.md)
|
||||
@@ -19,7 +19,6 @@
|
||||
- [RenderSceneData](RenderSceneData/RenderSceneData.md)
|
||||
- [VisibleRenderItem](VisibleRenderItem/VisibleRenderItem.md)
|
||||
- [VisibleVolumeItem](VisibleVolumeItem/VisibleVolumeItem.md)
|
||||
- [VisibleVolumeItem](VisibleVolumeItem/VisibleVolumeItem.md)
|
||||
|
||||
## 当前职责
|
||||
|
||||
@@ -28,7 +27,6 @@
|
||||
- 承载主方向光、阴影和 additional lights 快照
|
||||
- 承载 scene extraction 之后的 `visibleItems`
|
||||
- 承载 scene extraction 之后的 `visibleVolumes`
|
||||
- 承载 scene extraction 之后的 `visibleVolumes`
|
||||
|
||||
## 相关文档
|
||||
|
||||
|
||||
@@ -6,38 +6,49 @@
|
||||
|
||||
**头文件**: `XCEngine/Rendering/FrameData/VisibleVolumeItem.h`
|
||||
|
||||
**描述**: scene extraction 之后交给体积渲染阶段消费的一条可见体积记录,已经带上体积组件、体积资源、材质、渲染队列、相机距离和世界变换。
|
||||
**描述**: scene extraction 之后交给体积渲染阶段消费的一条可见体积记录,已经带上组件、资源、渲染队列、相机距离和世界变换。
|
||||
|
||||
## 字段
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `gameObject` | 来源场景对象。 |
|
||||
| `volumeRenderer` | 提供体积资源与阴影标志的组件。 |
|
||||
| `volumeField` | 当前解析出的体积资源。 |
|
||||
| `material` | 当前解析出的材质指针,可为空。 |
|
||||
| `renderQueue` | 当前体积项的渲染队列。 |
|
||||
| `cameraDistanceSq` | 到当前相机的距离平方。 |
|
||||
| `localToWorld` | 当前体积项的世界变换。 |
|
||||
| `gameObject` | 来源场景对象 |
|
||||
| `volumeRenderer` | 提供体积资源与阴影标志的组件 |
|
||||
| `volumeField` | 当前要渲染的体积资源 |
|
||||
| `material` | 当前体积对象使用的材质 |
|
||||
| `renderQueue` | 当前体积对象的渲染队列 |
|
||||
| `cameraDistanceSq` | 到当前相机的距离平方 |
|
||||
| `localToWorld` | 当前体积对象的世界变换 |
|
||||
|
||||
## 当前语义
|
||||
|
||||
- 只有对象上存在有效 [VolumeRendererComponent](../../../Components/VolumeRendererComponent/VolumeRendererComponent.md) 且体积资源可解析时,scene extraction 才会生成这条记录。
|
||||
- opaque / transparent 的排序规则同样会消费 `renderQueue` 与 `cameraDistanceSq`。
|
||||
- 这条记录与 [VisibleRenderItem](../VisibleRenderItem/VisibleRenderItem.md) 平行存在,前者服务体积链路,后者服务 mesh 链路。
|
||||
- 同一个 `GameObject` 至多展开成一条 `VisibleVolumeItem`,不像网格那样会按 section 细分。
|
||||
- `renderQueue` 与 `cameraDistanceSq` 当前会参与稳定排序:
|
||||
- opaque 队列按近到远
|
||||
- transparent 队列按远到近
|
||||
- `localToWorld` 当前直接来自 `TransformComponent::GetLocalToWorldMatrix()`,下游体积 pass 会据此构造 `model` 与 `inverseModel` 常量。
|
||||
|
||||
## 当前调用链
|
||||
## 测试与调用链
|
||||
|
||||
- `engine/src/Rendering/Extraction/RenderSceneUtility.cpp`
|
||||
- 负责构造 `VisibleVolumeItem`
|
||||
- 当前负责从 `VolumeRendererComponent` 组装本结构
|
||||
- `engine/src/Rendering/Extraction/RenderSceneExtractor.cpp`
|
||||
- 负责提取与排序 `sceneData.visibleVolumes`
|
||||
- [BuiltinVolumetricPass](../../Passes/BuiltinVolumetricPass/BuiltinVolumetricPass.md)
|
||||
- 当前消费 `visibleVolumes`
|
||||
- 当前对 `visibleVolumes` 执行稳定排序
|
||||
- `engine/src/Rendering/Passes/BuiltinVolumetricPass.cpp`
|
||||
- 当前直接消费本结构执行逐体积绘制
|
||||
- `tests/Rendering/unit/test_render_scene_extractor.cpp`
|
||||
- 覆盖可见体积提取、剔除和按 `renderQueue` 排序
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 这是 extraction 与 execution 之间的中间结构,不负责资源生命周期。
|
||||
- 本结构不记录 GPU 资源句柄;GPU 上传由 `RenderResourceCache` 处理。
|
||||
- 当前没有额外的体积 section、LOD 或 batching 语义。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [FrameData](../FrameData.md)
|
||||
- [VisibleRenderItem](../VisibleRenderItem/VisibleRenderItem.md)
|
||||
- [RenderSceneData](../RenderSceneData/RenderSceneData.md)
|
||||
- [VolumeRendererComponent](../../../Components/VolumeRendererComponent/VolumeRendererComponent.md)
|
||||
- [BuiltinVolumetricPass](../../Passes/BuiltinVolumetricPass/BuiltinVolumetricPass.md)
|
||||
- [RenderSceneUtility](../../Extraction/RenderSceneUtility/RenderSceneUtility.md)
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# BuiltinSelectionMaskPass::BuildInputLayout
|
||||
|
||||
```cpp
|
||||
static RHI::InputLayoutDesc BuildInputLayout();
|
||||
```
|
||||
|
||||
返回 selection-mask pass 的顶点布局。当前直接复用基类 `BuildCommonInputLayout()`。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [BuiltinSelectionMaskPass](BuiltinSelectionMaskPass.md)
|
||||
@@ -0,0 +1,40 @@
|
||||
# BuiltinSelectionMaskPass
|
||||
|
||||
**命名空间**: `XCEngine::Rendering::Passes`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**头文件**: `XCEngine/Rendering/Passes/BuiltinSelectionMaskPass.h`
|
||||
|
||||
**描述**: 选择遮罩 pass,在深度风格重绘框架上只重绘被选中对象,并把结果写入 selection mask 目标。
|
||||
|
||||
## 概览
|
||||
|
||||
`BuiltinSelectionMaskPass` 继承自 [BuiltinDepthStylePassBase](../BuiltinDepthStylePassBase/BuiltinDepthStylePassBase.md)。
|
||||
它不重新实现整套场景重绘框架,而是只增加“按选中对象过滤”的那层语义:
|
||||
|
||||
- 外部传入 `selectedObjectIds`
|
||||
- pass 内部记录到 `m_selectedObjectIds`
|
||||
- `ShouldRenderVisibleItem(...)` 只让被选中的对象通过
|
||||
|
||||
## 当前流程
|
||||
|
||||
1. [Render](Render.md) 记录选中对象 id 列表
|
||||
2. 若列表为空,直接返回 `false`
|
||||
3. 复制 `sceneData`,把 clear flags 改为纯颜色清屏且清为黑色
|
||||
4. 组装 `RenderPassContext`
|
||||
5. 调用基类 `Execute(...)`
|
||||
|
||||
## 公开方法
|
||||
|
||||
| 方法 | 说明 |
|
||||
|------|------|
|
||||
| [BuildInputLayout](BuildInputLayout.md) | 复用深度风格 pass 的通用顶点布局 |
|
||||
| [GetName](GetName.md) | 返回 `BuiltinSelectionMaskPass` |
|
||||
| [Render](Render.md) | 只重绘选中对象到 selection mask |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Passes](../Passes.md)
|
||||
- [BuiltinDepthStylePassBase](../BuiltinDepthStylePassBase/BuiltinDepthStylePassBase.md)
|
||||
- [BuiltinSelectionOutlinePass](../BuiltinSelectionOutlinePass/BuiltinSelectionOutlinePass.md)
|
||||
@@ -0,0 +1,11 @@
|
||||
# BuiltinSelectionMaskPass::GetName
|
||||
|
||||
```cpp
|
||||
const char* GetName() const override;
|
||||
```
|
||||
|
||||
返回固定名称 `BuiltinSelectionMaskPass`。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [BuiltinSelectionMaskPass](BuiltinSelectionMaskPass.md)
|
||||
@@ -0,0 +1,25 @@
|
||||
# BuiltinSelectionMaskPass::Render
|
||||
|
||||
```cpp
|
||||
bool Render(
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface,
|
||||
const RenderSceneData& sceneData,
|
||||
const std::vector<uint64_t>& selectedObjectIds);
|
||||
```
|
||||
|
||||
把当前选中对象重绘到 selection mask render target。
|
||||
|
||||
## 当前实现流程
|
||||
|
||||
1. 保存 `selectedObjectIds`
|
||||
2. 若选中列表为空,返回 `false`
|
||||
3. 复制输入 `sceneData`
|
||||
4. 把 `cameraData.clearFlags` 改为 `RenderClearFlags::Color`
|
||||
5. 把 clear color 固定为黑色
|
||||
6. 调用基类 `Execute(...)`
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [BuiltinSelectionMaskPass](BuiltinSelectionMaskPass.md)
|
||||
- [BuiltinSelectionOutlinePass](../BuiltinSelectionOutlinePass/BuiltinSelectionOutlinePass.md)
|
||||
@@ -0,0 +1,60 @@
|
||||
# BuiltinSelectionOutlinePass
|
||||
|
||||
**命名空间**: `XCEngine::Rendering::Passes`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**头文件**: `XCEngine/Rendering/Passes/BuiltinSelectionOutlinePass.h`
|
||||
|
||||
**描述**: 基于 selection mask 与 depth 纹理执行的全屏轮廓 pass,用于把选中描边叠加回主颜色目标。
|
||||
|
||||
## 概览
|
||||
|
||||
`BuiltinSelectionOutlinePass` 与 `BuiltinSelectionMaskPass` 分工明确:
|
||||
|
||||
- mask pass 负责把选中对象重绘成二值 mask
|
||||
- outline pass 负责读取 mask 与 depth,执行一次全屏三角形轮廓合成
|
||||
|
||||
它不是 `RenderPass` 子类,而是一个自管理资源的独立 helper。
|
||||
|
||||
## 当前执行流程
|
||||
|
||||
1. [Render](Render.md) 校验 render context、mask view、depth view 和 surface
|
||||
2. `EnsureInitialized(...)` 按后端、render target 格式和采样数准备 pipeline 资源
|
||||
3. 写入 outline 常量
|
||||
4. 更新 selection mask / depth 的 SRV 绑定
|
||||
5. 视情况做资源状态切换
|
||||
6. 绘制一次全屏三角形并恢复资源状态
|
||||
|
||||
## 关键资源
|
||||
|
||||
| 资源 | 说明 |
|
||||
|------|------|
|
||||
| `m_pipelineLayout` / `m_pipelineState` | 全屏 outline pass 的 pipeline |
|
||||
| `m_constantPool` / `m_constantSet` | outline 常量缓冲 |
|
||||
| `m_texturePool` / `m_textureSet` | selection mask 与 depth SRV |
|
||||
| `m_shaderPath` | 当前使用的 selection-outline shader 路径 |
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 只支持单颜色附件输出
|
||||
- 当前不写深度
|
||||
- 输出样式由 [SelectionOutlineStyle](../SelectionOutlineStyle/SelectionOutlineStyle.md) 控制
|
||||
- 输入纹理来源由 [SelectionOutlinePassInputs](../SelectionOutlinePassInputs/SelectionOutlinePassInputs.md) 描述
|
||||
|
||||
## 公开方法
|
||||
|
||||
| 方法 | 说明 |
|
||||
|------|------|
|
||||
| [Constructor](Constructor.md) | 创建 pass,可注入 shader 路径 |
|
||||
| [SetShaderPath](SetShaderPath.md) | 更新 shader 路径并清空已创建资源 |
|
||||
| [GetShaderPath](GetShaderPath.md) | 返回当前 shader 路径 |
|
||||
| [Render](Render.md) | 执行全屏描边合成 |
|
||||
| [Shutdown](Shutdown.md) | 销毁内部 RHI 资源 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Passes](../Passes.md)
|
||||
- [BuiltinSelectionMaskPass](../BuiltinSelectionMaskPass/BuiltinSelectionMaskPass.md)
|
||||
- [SelectionOutlineStyle](../SelectionOutlineStyle/SelectionOutlineStyle.md)
|
||||
- [SelectionOutlinePassInputs](../SelectionOutlinePassInputs/SelectionOutlinePassInputs.md)
|
||||
@@ -0,0 +1,17 @@
|
||||
# BuiltinSelectionOutlinePass::BuiltinSelectionOutlinePass
|
||||
|
||||
```cpp
|
||||
explicit BuiltinSelectionOutlinePass(Containers::String shaderPath = Containers::String());
|
||||
```
|
||||
|
||||
创建 selection outline pass。
|
||||
|
||||
## 当前语义
|
||||
|
||||
- 若传入空路径,默认回退到内建 selection-outline shader 路径
|
||||
- 构造后会立即调用内部 `ResetState()`
|
||||
- 资源真正创建发生在第一次 `Render(...)` 或后续 `EnsureInitialized(...)`
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [BuiltinSelectionOutlinePass](BuiltinSelectionOutlinePass.md)
|
||||
@@ -0,0 +1,12 @@
|
||||
# BuiltinSelectionOutlinePass::GetShaderPath
|
||||
|
||||
```cpp
|
||||
const Containers::String& GetShaderPath() const;
|
||||
```
|
||||
|
||||
返回当前记录的 selection-outline shader 路径。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [BuiltinSelectionOutlinePass](BuiltinSelectionOutlinePass.md)
|
||||
- [SetShaderPath](SetShaderPath.md)
|
||||
@@ -0,0 +1,27 @@
|
||||
# BuiltinSelectionOutlinePass::Render
|
||||
|
||||
```cpp
|
||||
bool Render(
|
||||
const RenderContext& renderContext,
|
||||
const RenderSurface& surface,
|
||||
const SelectionOutlinePassInputs& inputs,
|
||||
const SelectionOutlineStyle& style = {});
|
||||
```
|
||||
|
||||
读取 selection mask 与 depth,并把轮廓叠加回 `surface` 的主颜色目标。
|
||||
|
||||
## 当前实现流程
|
||||
|
||||
1. 校验 render context、mask/depth 纹理与 surface
|
||||
2. `EnsureInitialized(...)`
|
||||
3. 构建 `OutlineConstants`
|
||||
4. 写入常量并更新两个 SRV
|
||||
5. 自动状态切换开启时,把目标切到 `RenderTarget`、输入切到 `PixelShaderResource`
|
||||
6. 绑定两个 descriptor set,执行一次 `Draw(3, 1, 0, 0)`
|
||||
7. 恢复资源状态
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [BuiltinSelectionOutlinePass](BuiltinSelectionOutlinePass.md)
|
||||
- [SelectionOutlinePassInputs](../SelectionOutlinePassInputs/SelectionOutlinePassInputs.md)
|
||||
- [SelectionOutlineStyle](../SelectionOutlineStyle/SelectionOutlineStyle.md)
|
||||
@@ -0,0 +1,18 @@
|
||||
# BuiltinSelectionOutlinePass::SetShaderPath
|
||||
|
||||
```cpp
|
||||
void SetShaderPath(const Containers::String& shaderPath);
|
||||
```
|
||||
|
||||
更新 selection-outline shader 路径。
|
||||
|
||||
## 当前行为
|
||||
|
||||
- 若新旧路径相同,直接返回
|
||||
- 若路径发生变化,会先销毁已创建的 pipeline / descriptor 等资源
|
||||
- 后续首次 `Render(...)` 会按新路径重新初始化
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [BuiltinSelectionOutlinePass](BuiltinSelectionOutlinePass.md)
|
||||
- [GetShaderPath](GetShaderPath.md)
|
||||
@@ -0,0 +1,18 @@
|
||||
# BuiltinSelectionOutlinePass::Shutdown
|
||||
|
||||
```cpp
|
||||
void Shutdown();
|
||||
```
|
||||
|
||||
主动销毁 selection outline pass 已创建的 RHI 资源。
|
||||
|
||||
## 当前行为
|
||||
|
||||
- 释放 pipeline state、pipeline layout
|
||||
- 释放常量与纹理 descriptor pool / set
|
||||
- 清空已加载 shader 句柄
|
||||
- 重置缓存的 render target 格式与采样数
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [BuiltinSelectionOutlinePass](BuiltinSelectionOutlinePass.md)
|
||||
@@ -1,29 +1,18 @@
|
||||
# BuiltinVolumetricPass::BuildInputLayout
|
||||
|
||||
**命名空间**: `XCEngine::Rendering::Passes`
|
||||
|
||||
**类型**: `method`
|
||||
|
||||
**头文件**: `XCEngine/Rendering/Passes/BuiltinVolumetricPass.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
static RHI::InputLayoutDesc BuildInputLayout();
|
||||
```
|
||||
|
||||
## 作用
|
||||
返回体积绘制当前使用的顶点布局。
|
||||
|
||||
返回 `BuiltinVolumetricPass` 当前使用的顶点布局描述。
|
||||
## 当前布局
|
||||
|
||||
## 当前行为
|
||||
- `POSITION`
|
||||
- `NORMAL`
|
||||
- `TEXCOORD0`
|
||||
|
||||
- 当前布局直接基于 `Resources::StaticMeshVertex`。
|
||||
- 依次声明:
|
||||
- `POSITION`
|
||||
- `NORMAL`
|
||||
- `TEXCOORD0`
|
||||
- 说明体积 pass 当前复用静态网格顶点结构,而不是定义单独的体积代理顶点格式。
|
||||
这些元素都来自 `Resources::StaticMeshVertex`,说明体积 pass 当前沿用静态 mesh 顶点格式来绘制 cube proxy mesh。
|
||||
|
||||
## 相关文档
|
||||
|
||||
|
||||
@@ -6,66 +6,52 @@
|
||||
|
||||
**头文件**: `XCEngine/Rendering/Passes/BuiltinVolumetricPass.h`
|
||||
|
||||
**描述**: builtin 体积渲染 pass,消费 `RenderSceneData::visibleVolumes`,为每个可见体积解析 shader pass、管线状态、descriptor set 与 `VolumeField` GPU 资源后执行绘制。
|
||||
**描述**: 内建体积绘制 pass,使用 cube 代理网格、材质 shader pass 和体积资源描述符把可见体积绘制到当前颜色目标。
|
||||
|
||||
## 概览
|
||||
|
||||
`BuiltinVolumetricPass` 当前是体积渲染进入 builtin forward 链路的实际执行者。它不是独立的体积框架,而是围绕现有 scene-pass 体系补出的一条专用路径:
|
||||
`BuiltinVolumetricPass` 是当前体积渲染链路的核心执行器。
|
||||
它继承自 `RenderPass`,但和普通 mesh pass 相比有几处明显特点:
|
||||
|
||||
- 输入来自 `RenderSceneData::visibleVolumes`
|
||||
- 几何代理当前固定使用 builtin cube mesh
|
||||
- 资源绑定依赖 shader pass 的 builtin resource layout 解析
|
||||
- 当前只接受 `VolumeStorageKind::NanoVDB`
|
||||
- 几何始终来自 builtin cube mesh,而不是体积资源自带网格
|
||||
- 着色器必须声明 `PerObject` 与 `VolumeField` 资源绑定
|
||||
- descriptor set 与 pipeline state 会按 shader pass、材质和 volume SRV 动态缓存
|
||||
|
||||
## 当前执行流程
|
||||
|
||||
1. `Initialize(...)` / `EnsureInitialized(...)` 保证 device、backend 与 builtin cube mesh 就绪。
|
||||
2. `Execute(...)` 校验 `RenderContext`、颜色附件、深度附件和 render area。
|
||||
3. 遍历 `sceneData.visibleVolumes`。
|
||||
4. 每项调用 `DrawVisibleVolume(...)`:
|
||||
- 通过 `ResolveVolumeShaderPass(...)` 选择兼容的 volumetric shader pass
|
||||
- 通过 `GetOrCreatePassResourceLayout(...)` 创建或复用 pipeline layout
|
||||
- 通过 `GetOrCreatePipelineState(...)` 创建或复用 graphics pipeline
|
||||
- 通过 `RenderResourceCache` 获取 cube mesh 与 `VolumeField` 的 GPU 视图
|
||||
- 组装 `PerObjectConstants` 与 `LightingConstants`
|
||||
- 写 descriptor set 并提交 draw call
|
||||
1. [Initialize](Initialize.md) / `EnsureInitialized(...)` 加载 builtin cube mesh
|
||||
2. [Execute](Execute.md) 校验 `RenderSurface` 是否具备单颜色附件和深度附件
|
||||
3. 逐个遍历 `sceneData.visibleVolumes`
|
||||
4. 为每个体积解析兼容的 volumetric shader pass
|
||||
5. 构建或复用 pipeline layout、pipeline state 和动态 descriptor set
|
||||
6. 把体积 bounds、材质常量、主方向光常量与 volume SRV 绑定后提交 draw
|
||||
|
||||
## 关键资源约束
|
||||
## 关键内部状态
|
||||
|
||||
- 需要单一颜色附件和有效深度附件。
|
||||
- `BuiltinPassResourceBindingPlan` 里必须至少存在:
|
||||
- `PerObject`
|
||||
- `VolumeField`
|
||||
- 若 shader pass 还声明了 `Material`,则材质必须能提供有效的 schema constant payload。
|
||||
- 体积资源当前必须是 `NanoVDB`,否则该条目会被跳过。
|
||||
|
||||
## 当前缓存层
|
||||
|
||||
类内部当前维护三类缓存:
|
||||
|
||||
- `m_passResourceLayouts`
|
||||
- 以 `shader + passName` 为键缓存 pipeline layout 与 binding metadata
|
||||
- `m_pipelineStates`
|
||||
- 以 render state、shader、keyword signature、render target format 等为键缓存 pipeline state
|
||||
- `m_dynamicDescriptorSets`
|
||||
- 以 pass-layout、set、objectId、material、volumeField 为键缓存动态 descriptor set
|
||||
| 状态 | 说明 |
|
||||
|------|------|
|
||||
| `m_builtinCubeMesh` | 所有体积绘制共用的 cube proxy mesh |
|
||||
| `m_resourceCache` | 复用 mesh 与 volume GPU 资源 |
|
||||
| `m_passResourceLayouts` | 按 shader/pass 缓存资源布局 |
|
||||
| `m_pipelineStates` | 按 render state、shader、格式与 keyword 签名缓存 pipeline |
|
||||
| `m_dynamicDescriptorSets` | 按对象、材质、volume field 缓存动态描述符集 |
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- pass 本身不负责 scene extraction,也不负责决定 `visibleVolumes` 的排序策略。
|
||||
- 当前代理几何固定为 builtin cube,而不是从体数据本身生成裁剪几何。
|
||||
- 当前 lighting constants 只消费主方向光。
|
||||
- 资源清理通过 `Shutdown()` / 析构集中处理。
|
||||
- 只处理 `VisibleVolumeItem`
|
||||
- 只接受 `VolumeStorageKind::NanoVDB`
|
||||
- 当前要求 surface 为“单颜色附件 + 深度附件”模型
|
||||
- 若 shader pass 未声明 `PerObject` 或 `VolumeField` 绑定,会直接失败而不是做 legacy fallback
|
||||
|
||||
## 公开方法
|
||||
|
||||
| 方法 | 说明 |
|
||||
|------|------|
|
||||
| [BuildInputLayout](BuildInputLayout.md) | 构建当前体积 pass 使用的顶点布局。 |
|
||||
| [GetName](GetName.md) | 返回 pass 名称。 |
|
||||
| [Initialize](Initialize.md) | 预热 device/backend 相关资源。 |
|
||||
| [Execute](Execute.md) | 遍历 `visibleVolumes` 并提交绘制。 |
|
||||
| [Shutdown](Shutdown.md) | 销毁缓存的管线、descriptor 与资源状态。 |
|
||||
| [BuildInputLayout](BuildInputLayout.md) | 返回体积 pass 使用的顶点布局 |
|
||||
| [GetName](GetName.md) | 返回 pass 名称 |
|
||||
| [Initialize](Initialize.md) | 预热 builtin cube mesh 等资源 |
|
||||
| [Execute](Execute.md) | 绘制所有可见体积 |
|
||||
| [Shutdown](Shutdown.md) | 销毁缓存的 RHI 资源 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
|
||||
@@ -1,31 +1,24 @@
|
||||
# BuiltinVolumetricPass::Execute
|
||||
|
||||
**命名空间**: `XCEngine::Rendering::Passes`
|
||||
|
||||
**类型**: `method`
|
||||
|
||||
**头文件**: `XCEngine/Rendering/Passes/BuiltinVolumetricPass.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
bool Execute(const RenderPassContext& context) override;
|
||||
```
|
||||
|
||||
## 作用
|
||||
把 `context.sceneData.visibleVolumes` 中的体积绘制到当前 render target。
|
||||
|
||||
遍历 `visibleVolumes`,为每个可见体积提交一次 volumetric draw。
|
||||
## 当前实现流程
|
||||
|
||||
## 当前行为
|
||||
1. 校验 `renderContext`
|
||||
2. 若 `visibleVolumes` 为空,直接返回 `true`
|
||||
3. 要求 surface 具备单颜色附件、深度附件和有效 render area
|
||||
4. 设置 viewport、scissor 和 triangle-list topology
|
||||
5. 逐个调用内部 `DrawVisibleVolume(...)`
|
||||
|
||||
- `renderContext` 无效时返回 `false`。
|
||||
- `visibleVolumes` 为空时直接返回 `true`,表示“没有工作但不算失败”。
|
||||
- 要求:
|
||||
- 单一颜色附件
|
||||
- 非空深度附件
|
||||
- 正常的 `renderArea`
|
||||
- 会设置 render target、viewport、scissor 和三角形拓扑。
|
||||
- 最终逐项调用内部 `DrawVisibleVolume(...)`。
|
||||
## 关键语义
|
||||
|
||||
- 这里不负责 scene extraction;输入必须已经是 `VisibleVolumeItem`
|
||||
- 体积绘制依赖材质 shader pass 与 volume SRV 都已可用
|
||||
- 某个体积绘制失败不会自动切换为其他 shader 或 fallback path
|
||||
|
||||
## 相关文档
|
||||
|
||||
|
||||
@@ -1,24 +1,10 @@
|
||||
# BuiltinVolumetricPass::GetName
|
||||
|
||||
**命名空间**: `XCEngine::Rendering::Passes`
|
||||
|
||||
**类型**: `method`
|
||||
|
||||
**头文件**: `XCEngine/Rendering/Passes/BuiltinVolumetricPass.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
const char* GetName() const override;
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
返回当前 pass 的稳定名称。
|
||||
|
||||
## 当前行为
|
||||
|
||||
- 固定返回 `"BuiltinVolumetricPass"`。
|
||||
返回固定名称 `BuiltinVolumetricPass`。
|
||||
|
||||
## 相关文档
|
||||
|
||||
|
||||
@@ -1,28 +1,18 @@
|
||||
# BuiltinVolumetricPass::Initialize
|
||||
|
||||
**命名空间**: `XCEngine::Rendering::Passes`
|
||||
|
||||
**类型**: `method`
|
||||
|
||||
**头文件**: `XCEngine/Rendering/Passes/BuiltinVolumetricPass.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
bool Initialize(const RenderContext& context) override;
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
预热当前 device/backend 相关资源。
|
||||
预热体积 pass 依赖的基础资源。
|
||||
|
||||
## 当前行为
|
||||
|
||||
- 直接转发到内部 `EnsureInitialized(context)`。
|
||||
- 若 device/backend 变化,旧缓存会先被 `DestroyResources()` 清掉,再重新创建。
|
||||
- 当前初始化阶段最关键的资源是 builtin cube mesh。
|
||||
- 实际入口会转到内部 `EnsureInitialized(...)`
|
||||
- 当前最关键的初始化工作是加载 builtin cube mesh
|
||||
- 若 `RenderContext` 无效或 cube mesh 加载失败,返回 `false`
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [BuiltinVolumetricPass](BuiltinVolumetricPass.md)
|
||||
- [Shutdown](Shutdown.md)
|
||||
- [Execute](Execute.md)
|
||||
|
||||
@@ -1,33 +1,19 @@
|
||||
# BuiltinVolumetricPass::Shutdown
|
||||
|
||||
**命名空间**: `XCEngine::Rendering::Passes`
|
||||
|
||||
**类型**: `method`
|
||||
|
||||
**头文件**: `XCEngine/Rendering/Passes/BuiltinVolumetricPass.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
void Shutdown() override;
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
销毁 `BuiltinVolumetricPass` 当前持有的缓存资源。
|
||||
销毁体积 pass 缓存的 GPU 资源与运行时状态。
|
||||
|
||||
## 当前行为
|
||||
|
||||
- 转发到 `DestroyResources()`。
|
||||
- 会清理:
|
||||
- `RenderResourceCache`
|
||||
- 所有 pipeline state
|
||||
- 所有动态 descriptor set
|
||||
- 所有 pass resource layout
|
||||
- builtin cube mesh 句柄
|
||||
- 最后把 device/backend 状态恢复到初始值。
|
||||
- 关闭 `RenderResourceCache`
|
||||
- 释放缓存的 pipeline state
|
||||
- 释放动态 descriptor set 与 pool
|
||||
- 释放按 shader pass 建立的 pipeline layout / set layout 元数据
|
||||
- 清空 builtin cube mesh 句柄
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [BuiltinVolumetricPass](BuiltinVolumetricPass.md)
|
||||
- [Initialize](Initialize.md)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
**类型**: `submodule`
|
||||
|
||||
**描述**: 承载 builtin object-id、selection outline、infinite grid、fullscreen post-process / final-color,以及 depth-only / shadow-caster 一类可复用渲染 pass 与配套参数类型。
|
||||
**描述**: 承载 builtin object-id、selection mask / outline、volumetric、infinite grid、fullscreen post-process / final-color,以及 depth-only / shadow-caster 一类可复用渲染 pass 与配套参数类型。
|
||||
|
||||
## 概览
|
||||
|
||||
@@ -12,7 +12,10 @@
|
||||
|
||||
- [BuiltinObjectIdPass](BuiltinObjectIdPass/BuiltinObjectIdPass.md) 把可见物体编码成 object-id 颜色,写到辅助渲染目标。
|
||||
- [BuiltinObjectIdOutlinePass](BuiltinObjectIdOutlinePass/BuiltinObjectIdOutlinePass.md) 读取 object-id 纹理和选中对象列表,把轮廓或调试 mask 叠加回场景颜色。
|
||||
- [BuiltinSelectionMaskPass](BuiltinSelectionMaskPass/BuiltinSelectionMaskPass.md) 重绘当前选中对象,生成 selection mask。
|
||||
- [BuiltinSelectionOutlinePass](BuiltinSelectionOutlinePass/BuiltinSelectionOutlinePass.md) 读取 selection-mask 与 depth 纹理,在主颜色目标上合成轮廓。
|
||||
- [BuiltinInfiniteGridPass](BuiltinInfiniteGridPass/BuiltinInfiniteGridPass.md) 给 Scene View 一类编辑器视口叠加无限网格。
|
||||
- [BuiltinVolumetricPass](BuiltinVolumetricPass/BuiltinVolumetricPass.md) 消费 `visibleVolumes` 与 `VolumeField` GPU 资源,执行体渲染。
|
||||
- [BuiltinColorScalePostProcessPass](BuiltinColorScalePostProcessPass/BuiltinColorScalePostProcessPass.md) 执行基于 `sourceColorView` 的全屏颜色缩放后处理。
|
||||
- [BuiltinFinalColorPass](BuiltinFinalColorPass/BuiltinFinalColorPass.md) 执行 exposure、tone mapping、output transfer 和 final color scale 的最终输出阶段。
|
||||
- [BuiltinDepthStylePassBase](BuiltinDepthStylePassBase/BuiltinDepthStylePassBase.md) 为深度风格场景重绘 pass 提供共享执行骨架。
|
||||
@@ -28,7 +31,7 @@
|
||||
1. [CameraRenderer](../CameraRenderer/CameraRenderer.md) 先执行主 `RenderPipeline`。
|
||||
2. 如果 [CameraRenderRequest](../CameraRenderRequest/CameraRenderRequest.md) 里请求了 `objectId.surface`,则额外执行 [BuiltinObjectIdPass](BuiltinObjectIdPass/BuiltinObjectIdPass.md)。
|
||||
3. editor 侧的 `SceneViewportRenderPlan` 再构建 `postScenePasses` 和 `overlayPasses`。
|
||||
4. 其中 `SceneViewportGridPass` / `SceneViewportSelectionOutlinePass` 最终分别调用 [BuiltinInfiniteGridPass](BuiltinInfiniteGridPass/BuiltinInfiniteGridPass.md) 和 [BuiltinObjectIdOutlinePass](BuiltinObjectIdOutlinePass/BuiltinObjectIdOutlinePass.md)。
|
||||
4. 其中 `SceneViewportGridPass` / `SceneViewportSelectionOutlinePass` 当前分别调用 [BuiltinInfiniteGridPass](BuiltinInfiniteGridPass/BuiltinInfiniteGridPass.md) 与“[BuiltinSelectionMaskPass](BuiltinSelectionMaskPass/BuiltinSelectionMaskPass.md) + [BuiltinSelectionOutlinePass](BuiltinSelectionOutlinePass/BuiltinSelectionOutlinePass.md)”这一组 selection outline 组合。
|
||||
|
||||
### Fullscreen post-process / final-color
|
||||
|
||||
@@ -48,13 +51,24 @@
|
||||
4. `postScenePasses`
|
||||
5. `overlayPasses`
|
||||
|
||||
### Builtin volume scene pass
|
||||
|
||||
体渲染链路和前面两类流程不同,它不是 post-process,而是 builtin scene pass:
|
||||
|
||||
1. `RenderSceneExtractor` 先把体积对象提取到 `visibleVolumes`。
|
||||
2. [BuiltinForwardPipeline](../Pipelines/BuiltinForwardPipeline/BuiltinForwardPipeline.md) 把 [BuiltinVolumetricPass](BuiltinVolumetricPass/BuiltinVolumetricPass.md) 放进自己的 pass sequence。
|
||||
3. `BuiltinVolumetricPass` 再按材质 shader pass、volume-field 绑定和 lighting 常量逐项绘制。
|
||||
|
||||
## 当前公开概念
|
||||
|
||||
| 类型 / 页面 | 角色 |
|
||||
|------|------|
|
||||
| [BuiltinObjectIdPass](BuiltinObjectIdPass/BuiltinObjectIdPass.md) | 生成 object-id 颜色缓冲。 |
|
||||
| [BuiltinObjectIdOutlinePass](BuiltinObjectIdOutlinePass/BuiltinObjectIdOutlinePass.md) | 在主颜色目标上合成选中轮廓。 |
|
||||
| [BuiltinSelectionMaskPass](BuiltinSelectionMaskPass/BuiltinSelectionMaskPass.md) | 为选中轮廓链路生成 selection mask。 |
|
||||
| [BuiltinSelectionOutlinePass](BuiltinSelectionOutlinePass/BuiltinSelectionOutlinePass.md) | 基于 selection-mask 与 depth 的全屏轮廓合成器。 |
|
||||
| [BuiltinInfiniteGridPass](BuiltinInfiniteGridPass/BuiltinInfiniteGridPass.md) | Scene View 网格覆盖层的底层执行 pass。 |
|
||||
| [BuiltinVolumetricPass](BuiltinVolumetricPass/BuiltinVolumetricPass.md) | builtin forward 链路中的体渲染 scene pass。 |
|
||||
| [BuiltinColorScalePostProcessPass](BuiltinColorScalePostProcessPass/BuiltinColorScalePostProcessPass.md) | 相机 post-process 栈当前的颜色缩放全屏 pass。 |
|
||||
| [BuiltinFinalColorPass](BuiltinFinalColorPass/BuiltinFinalColorPass.md) | final-color 阶段的最终合成 / 输出变换 pass。 |
|
||||
| [BuiltinDepthStylePassBase](BuiltinDepthStylePassBase/BuiltinDepthStylePassBase.md) | depth-only / shadow-caster 场景重绘共享的执行骨架。 |
|
||||
@@ -66,19 +80,27 @@
|
||||
- `tests/Rendering/unit/test_camera_scene_renderer.cpp` 验证了 `CameraRenderer` 里 object-id、post-process、final-output 与可选 pass sequence 的接入时机。
|
||||
- `engine/src/Rendering/Execution/CameraRenderer.cpp` 当前把 [BuiltinShadowCasterPass](BuiltinShadowCasterPass/BuiltinShadowCasterPass.md) 与 [BuiltinDepthOnlyPass](BuiltinDepthOnlyPass/BuiltinDepthOnlyPass.md) 作为默认 scene pass 挂进 `shadowCaster` / `depthOnly` request。
|
||||
- `engine/src/Rendering/Execution/SceneRenderer.cpp` 当前负责把 fullscreen 阶段写进 `CameraRenderRequest`。
|
||||
- `editor/src/Viewport/Passes/SceneViewportSelectionOutlinePass.h` 当前组合 [BuiltinSelectionMaskPass](BuiltinSelectionMaskPass/BuiltinSelectionMaskPass.md) 与 [BuiltinSelectionOutlinePass](BuiltinSelectionOutlinePass/BuiltinSelectionOutlinePass.md)。
|
||||
- `engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp` 当前把 [BuiltinVolumetricPass](BuiltinVolumetricPass/BuiltinVolumetricPass.md) 挂进 builtin forward pass sequence。
|
||||
- `tests/Rendering/unit/test_builtin_forward_pipeline.cpp` 验证了 `VolumeField` 资源语义与布局元数据。
|
||||
- `tests/Editor/test_viewport_render_flow_utils.cpp` 验证了 Scene View render plan 如何组装 grid / selection outline / overlay pass。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 这一层目前是 builtin、轻量、偏 editor/工具链导向的 pass 集合,还不是通用 render graph。
|
||||
- object-id 相关流程依赖单独的辅助 render target / shader resource view,而不是直接从主颜色结果反推。
|
||||
- selection outline 当前已经拆成“mask 重绘 + fullscreen compositing”两层,而不是单个对象列表后处理。
|
||||
- volumetric pass 当前依赖 `visibleVolumes`、`VolumeField` 资源绑定和 builtin cube proxy,不是独立 volume framework。
|
||||
- fullscreen pass 依赖调用方准备 `sourceColorView` 和中间表面;单个 pass 本身不管理整条阶段链。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [BuiltinObjectIdPass](BuiltinObjectIdPass/BuiltinObjectIdPass.md)
|
||||
- [BuiltinObjectIdOutlinePass](BuiltinObjectIdOutlinePass/BuiltinObjectIdOutlinePass.md)
|
||||
- [BuiltinSelectionMaskPass](BuiltinSelectionMaskPass/BuiltinSelectionMaskPass.md)
|
||||
- [BuiltinSelectionOutlinePass](BuiltinSelectionOutlinePass/BuiltinSelectionOutlinePass.md)
|
||||
- [BuiltinInfiniteGridPass](BuiltinInfiniteGridPass/BuiltinInfiniteGridPass.md)
|
||||
- [BuiltinVolumetricPass](BuiltinVolumetricPass/BuiltinVolumetricPass.md)
|
||||
- [BuiltinColorScalePostProcessPass](BuiltinColorScalePostProcessPass/BuiltinColorScalePostProcessPass.md)
|
||||
- [BuiltinFinalColorPass](BuiltinFinalColorPass/BuiltinFinalColorPass.md)
|
||||
- [BuiltinDepthStylePassBase](BuiltinDepthStylePassBase/BuiltinDepthStylePassBase.md)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
# SelectionOutlinePassInputs
|
||||
|
||||
**命名空间**: `XCEngine::Rendering::Passes`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEngine/Rendering/Passes/BuiltinSelectionOutlinePass.h`
|
||||
|
||||
**描述**: selection outline pass 的输入纹理描述,指定 selection mask、depth view 及其进入 pass 前的资源状态。
|
||||
|
||||
## 字段
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `selectionMaskTextureView` | selection mask 纹理视图 |
|
||||
| `selectionMaskState` | selection mask 当前资源状态 |
|
||||
| `depthTextureView` | 深度纹理视图 |
|
||||
| `depthTextureState` | 深度纹理当前资源状态 |
|
||||
|
||||
## 当前作用
|
||||
|
||||
- 为 `BuiltinSelectionOutlinePass::Render(...)` 提供两个输入 SRV
|
||||
- 在 surface 开启自动状态切换时,提供“切入 pass 前”的原始状态以便恢复
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [BuiltinSelectionOutlinePass](../BuiltinSelectionOutlinePass/BuiltinSelectionOutlinePass.md)
|
||||
- [SelectionOutlineStyle](../SelectionOutlineStyle/SelectionOutlineStyle.md)
|
||||
@@ -0,0 +1,22 @@
|
||||
# SelectionOutlineStyle
|
||||
|
||||
**命名空间**: `XCEngine::Rendering::Passes`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**头文件**: `XCEngine/Rendering/Passes/BuiltinSelectionOutlinePass.h`
|
||||
|
||||
**描述**: selection outline pass 的样式配置,当前控制描边颜色、像素宽度和调试遮罩模式。
|
||||
|
||||
## 默认值
|
||||
|
||||
| 字段 | 默认值 | 说明 |
|
||||
|------|------|------|
|
||||
| `outlineColor` | `Math::Color(1.0f, 0.4f, 0.0f, 1.0f)` | 默认橙色描边 |
|
||||
| `outlineWidthPixels` | `2.0f` | 描边宽度,单位像素 |
|
||||
| `debugSelectionMask` | `false` | 默认输出描边而不是直接显示 mask |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [BuiltinSelectionOutlinePass](../BuiltinSelectionOutlinePass/BuiltinSelectionOutlinePass.md)
|
||||
- [SelectionOutlinePassInputs](../SelectionOutlinePassInputs/SelectionOutlinePassInputs.md)
|
||||
@@ -25,7 +25,6 @@
|
||||
- [Shader](Shader/Shader.md)
|
||||
- [Texture](Texture/Texture.md)
|
||||
- [Volume](Volume/Volume.md)
|
||||
- [Volume](Volume/Volume.md)
|
||||
|
||||
## 头文件
|
||||
|
||||
|
||||
@@ -4,25 +4,20 @@
|
||||
|
||||
**类型**: `submodule`
|
||||
|
||||
**描述**: 体积资源子模块,承载 `VolumeField` 运行时资源对象与 `VolumeFieldLoader` 的 `.nvdb` / `.xcvol` 加载链路。
|
||||
**描述**: 体积资源子模块,覆盖体积 payload 运行时资源与对应的 loader。
|
||||
|
||||
## 概览
|
||||
## 概述
|
||||
|
||||
该目录与 `XCEngine/Resources/Volume` 对应的 public headers 保持平行,用于承载唯一的 canonical API 文档入口。
|
||||
`Resources::Volume` 当前是 NanoVDB 体积资源进入资源系统与渲染系统的汇合点。按当前实现,主链路是:
|
||||
|
||||
当前 `Resources/Volume` 这条链路主要覆盖两件事:
|
||||
|
||||
- [VolumeField](VolumeField/VolumeField.md)
|
||||
- 运行时体积资源对象,保存 payload、边界、体素尺寸和 grid 元数据。
|
||||
- [VolumeFieldLoader](VolumeFieldLoader/VolumeFieldLoader.md)
|
||||
- 负责 source `.nvdb` 与 artifact `.xcvol` 的加载。
|
||||
|
||||
## 当前主链路
|
||||
|
||||
1. 项目里的 `.nvdb` 体积文件通过 `VolumeFieldLoader` 读取。
|
||||
2. `AssetDatabase` 会把可复用的导入结果写成 `.xcvol` artifact。
|
||||
3. 运行时或编辑器通过 `ResourceManager` 加载 `VolumeField`。
|
||||
4. 渲染侧再通过 `RenderResourceCache` 把 `VolumeField` payload 上传成 GPU 可读结构化缓冲。
|
||||
1. `VolumeFieldLoader`
|
||||
- 读取 `.nvdb` 源文件或 `.xcvol` artifact
|
||||
2. `VolumeField`
|
||||
- 保存体积 payload 与边界元数据
|
||||
3. `VolumeRendererComponent`
|
||||
- 把资源挂到场景对象
|
||||
4. `RenderSceneExtractor` / `BuiltinVolumetricPass`
|
||||
- 提取并绘制体积对象
|
||||
|
||||
## 头文件
|
||||
|
||||
@@ -31,8 +26,6 @@
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [AssetDatabase](../../Core/Asset/AssetDatabase/AssetDatabase.md)
|
||||
- [ArtifactFormats](../../Core/Asset/ArtifactFormats/ArtifactFormats.md)
|
||||
- [RenderResourceCache](../../Rendering/RenderResourceCache/RenderResourceCache.md)
|
||||
- [上级目录](../Resources.md)
|
||||
- [API 总索引](../../../main.md)
|
||||
- [Resources](../Resources.md)
|
||||
- [VolumeRendererComponent](../../Components/VolumeRendererComponent/VolumeRendererComponent.md)
|
||||
- [BuiltinVolumetricPass](../../Rendering/Passes/BuiltinVolumetricPass/BuiltinVolumetricPass.md)
|
||||
|
||||
@@ -2,66 +2,63 @@
|
||||
|
||||
**命名空间**: `XCEngine::Resources`
|
||||
|
||||
**类型**: `enum + struct + class`
|
||||
**类型**: `class`
|
||||
|
||||
**头文件**: `XCEngine/Resources/Volume/VolumeField.h`
|
||||
|
||||
**源文件**: `engine/src/Resources/Volume/VolumeField.cpp`
|
||||
|
||||
**描述**: 体积资源对象,保存体积 payload、包围盒、体素尺寸、index bounds 与 grid 元数据,供资源系统、资产导入链路和体积渲染 pass 共同消费。
|
||||
**描述**: 体积 payload 的运行时资源对象,保存存储类型、包围盒、体素尺寸、索引边界和原始字节载荷。
|
||||
|
||||
## 声明概览
|
||||
## 概述
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `VolumeStorageKind` | `enum class` | 当前体积 payload 的存储格式,现阶段主要是 `NanoVDB`。 |
|
||||
| `VolumeIndexBounds` | `struct` | 体素索引空间的最小/最大坐标范围,并提供 `==` / `!=`。 |
|
||||
| `VolumeField` | `class` | 运行时体积资源对象。 |
|
||||
`VolumeField` 是当前体积资源在运行时的最小封装。它并不解析体积体素内容,而是把 loader 导入的 payload 和元数据原样保存下来,供后续:
|
||||
|
||||
## 当前资源模型
|
||||
- 场景组件绑定
|
||||
- artifact 重建
|
||||
- `RenderResourceCache` 上传 structured-buffer
|
||||
|
||||
`VolumeField` 继承 `IResource`,因此同时具备两层信息:
|
||||
使用。
|
||||
|
||||
- 资源身份
|
||||
- `name`
|
||||
- `path`
|
||||
- `guid`
|
||||
- `memorySize`
|
||||
- 体积内容
|
||||
- `storageKind`
|
||||
- `bounds`
|
||||
- `voxelSize`
|
||||
- `indexBounds`
|
||||
- `gridType`
|
||||
- `gridClass`
|
||||
- 原始 payload
|
||||
## 当前状态模型
|
||||
|
||||
这意味着它不是“只给渲染器看的裸 payload 缓冲”,而是资源系统可缓存、可导入、可按 `AssetRef` 恢复的正式资源对象。
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `m_storageKind` | 当前体积存储类型,现阶段主要是 `NanoVDB` |
|
||||
| `m_bounds` | 体积世界/局部包围盒 |
|
||||
| `m_voxelSize` | 体素尺寸 |
|
||||
| `m_indexBounds` | 体素索引空间边界 |
|
||||
| `m_gridType` / `m_gridClass` | NanoVDB metadata 的轻量转存 |
|
||||
| `m_payload` | 原始 payload 字节数组 |
|
||||
|
||||
## 创建与读取语义
|
||||
## 当前实现行为
|
||||
|
||||
- `Create(...)` 要求 `payload != nullptr` 且 `payloadSize > 0`,否则直接失败。
|
||||
- 创建成功后会拷贝整份 payload,而不是只保存外部指针。
|
||||
- `GetWorldBounds()` 当前直接返回 `m_bounds`,尚未引入独立的局部/世界体积边界变换语义。
|
||||
- `GetPayloadData()` / `GetPayloadSize()` 暴露的是当前缓存 payload,用于后续 GPU 上传。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前正式声明的存储格式只有 `Unknown` 与 `NanoVDB`。
|
||||
- `VolumeField` 自身不负责解析 `.nvdb` 文件格式;格式解析由 [VolumeFieldLoader](../VolumeFieldLoader/VolumeFieldLoader.md) 完成。
|
||||
- 运行时 `memorySize` 由 `UpdateMemorySize()` 基于对象本体、资源身份字符串和 payload 大小估算。
|
||||
- `Create(...)`
|
||||
- `payload == nullptr` 或 `payloadSize == 0` 时直接失败
|
||||
- 成功时会复制整份 payload,而不是借用外部内存
|
||||
- 会写入边界、体素尺寸、索引边界与 grid metadata
|
||||
- 成功后把资源标记为 valid,并更新 `memorySize`
|
||||
- `GetWorldBounds()` 当前只是 `GetBounds()` 的别名
|
||||
- `Release()` 当前直接执行 `delete this`
|
||||
|
||||
## 测试与调用链
|
||||
|
||||
- `tests/Resources/Volume/test_volume_field.cpp`
|
||||
- 覆盖 `Create(...)` 对 payload、bounds、voxelSize、indexBounds、gridType、gridClass 的保留行为。
|
||||
- 覆盖 payload 拷贝、边界元数据与 `GetMemorySize()`
|
||||
- `engine/src/Core/Asset/AssetDatabase.cpp`
|
||||
- 当前会把本资源写回 `.xcvol` artifact
|
||||
- `engine/src/Rendering/Caches/RenderResourceCache.cpp`
|
||||
- 当前会读取 payload 并把它上传成 GPU 结构化缓冲。
|
||||
- [BuiltinVolumetricPass](../../../Rendering/Passes/BuiltinVolumetricPass/BuiltinVolumetricPass.md)
|
||||
- 通过 `RenderResourceCache` 消费 `VolumeField`。
|
||||
- 当前把 payload 上传成体积 structured-buffer
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前只保存 payload,不提供体素级查询 API。
|
||||
- `Create(...)` 是一次性初始化入口,没有增量修改协议。
|
||||
- `GetWorldBounds()` 尚未引入独立于 `GetBounds()` 的额外变换语义。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Volume](../Volume.md)
|
||||
- [VolumeFieldLoader](../VolumeFieldLoader/VolumeFieldLoader.md)
|
||||
- [RenderResourceCache](../../../Rendering/RenderResourceCache/RenderResourceCache.md)
|
||||
- [VolumeRendererComponent](../../../Components/VolumeRendererComponent/VolumeRendererComponent.md)
|
||||
- [BuiltinVolumetricPass](../../../Rendering/Passes/BuiltinVolumetricPass/BuiltinVolumetricPass.md)
|
||||
|
||||
@@ -6,60 +6,89 @@
|
||||
|
||||
**头文件**: `XCEngine/Resources/Volume/VolumeFieldLoader.h`
|
||||
|
||||
**源文件**: `engine/src/Resources/Volume/VolumeFieldLoader.cpp`
|
||||
**描述**: `VolumeField` 的资源 loader,负责识别 `.nvdb` 与 `.xcvol`,并把体积文件转换成运行时 `VolumeField` 资源。
|
||||
|
||||
**描述**: `VolumeField` 资源加载器,负责识别 source `.nvdb` 与 artifact `.xcvol` 路径,并把它们统一转换成 `VolumeField` 资源对象。
|
||||
## 概述
|
||||
|
||||
## 概览
|
||||
`VolumeFieldLoader` 继承自 `IResourceLoader`,是当前体积资源进入 `ResourceManager` 的标准入口。它支持两类输入:
|
||||
|
||||
`VolumeFieldLoader` 当前承载两条正式加载路径:
|
||||
- `.xcvol`
|
||||
- 由 `AssetDatabase` 产出的正式 artifact
|
||||
- `.nvdb`
|
||||
- 原始 NanoVDB 源文件
|
||||
|
||||
1. `.xcvol`
|
||||
- 读取引擎自己的体积 artifact 格式。
|
||||
2. `.nvdb`
|
||||
- 在启用 `XCENGINE_HAS_NANOVDB` 时直接读取 NanoVDB source 文件。
|
||||
## 当前实现行为
|
||||
|
||||
因此它既是运行时加载器,也是 `AssetDatabase` 体积导入链路的核心入口。
|
||||
### 扩展名与资源类型
|
||||
|
||||
## 当前加载模型
|
||||
- `GetResourceType()` 固定返回 `ResourceType::VolumeField`
|
||||
- `GetSupportedExtensions()` 当前返回:
|
||||
- `nvdb`
|
||||
- `xcvol`
|
||||
- `CanLoad(...)` 只接受这两种扩展名
|
||||
|
||||
- `GetSupportedExtensions()` 当前返回 `nvdb` 和 `xcvol`。
|
||||
- `CanLoad(...)` 只按扩展名判定,不预先验证文件存在。
|
||||
- 相对路径会先尝试当前路径;若不存在,再回退到 `ResourceManager::Get().GetResourceRoot()`。
|
||||
- `.xcvol` 路径会读取 `VolumeFieldArtifactHeader`,要求:
|
||||
- `magic == "XCVOL02"`
|
||||
- schema 版本匹配
|
||||
- `payloadSize > 0`
|
||||
- `.nvdb` 路径在支持 NanoVDB 时会读取 grid metadata,并回填:
|
||||
- `bounds`
|
||||
### `.xcvol` artifact
|
||||
|
||||
加载 `.xcvol` 时,当前实现会:
|
||||
|
||||
1. 解析真实路径,必要时拼接 `ResourceManager::Get().GetResourceRoot()`
|
||||
2. 读取 `VolumeFieldArtifactHeader`
|
||||
3. 校验:
|
||||
- `magic == "XCVOL02"`
|
||||
- `schemaVersion == kVolumeFieldArtifactSchemaVersion`
|
||||
- `payloadSize > 0`
|
||||
4. 读取 payload 与体积元数据
|
||||
5. 构造 `VolumeField`
|
||||
|
||||
### `.nvdb` 源文件
|
||||
|
||||
只有在定义 `XCENGINE_HAS_NANOVDB` 时,当前 loader 才支持直接加载 `.nvdb` 源文件。成功时会:
|
||||
|
||||
- 通过 `nanovdb::io::readGrid(...)` 读取 grid payload
|
||||
- 从 `GridMetaData` 中提取:
|
||||
- `worldBBox`
|
||||
- `voxelSize`
|
||||
- `indexBounds`
|
||||
- `indexBBox`
|
||||
- `gridType`
|
||||
- `gridClass`
|
||||
- 构造 `VolumeField`
|
||||
|
||||
如果当前构建未启用 NanoVDB,则 `.nvdb` 会返回失败结果,而不是静默降级。
|
||||
|
||||
### 默认设置与注册
|
||||
|
||||
- `GetDefaultSettings()` 当前返回 `nullptr`
|
||||
- 文件末尾通过 `REGISTER_RESOURCE_LOADER(VolumeFieldLoader)` 注册到资源系统
|
||||
|
||||
## 测试与调用链
|
||||
|
||||
- `tests/Resources/Volume/test_volume_field_loader.cpp`
|
||||
- 覆盖扩展名识别
|
||||
- 覆盖源 `.nvdb` 读取
|
||||
- 覆盖 `AssetDatabase` 产出 `.xcvol` 后的复用
|
||||
- 覆盖 `ResourceManager` 按 `AssetRef` 加载体积资源
|
||||
- `engine/src/Core/Asset/AssetDatabase.cpp`
|
||||
- 当前使用本 loader 导入体积资产并生成 artifact
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 未启用 `XCENGINE_HAS_NANOVDB` 时,source `.nvdb` 会返回 `NanoVDB source-file support is unavailable in this build`。
|
||||
- `GetDefaultSettings()` 当前固定返回 `nullptr`,说明这条导入链路暂时没有独立的 volume import settings 对象。
|
||||
- 当前 loader 通过 `REGISTER_RESOURCE_LOADER(VolumeFieldLoader)` 注册到资源系统。
|
||||
- `.nvdb` 源文件直读依赖编译期开关 `XCENGINE_HAS_NANOVDB`。
|
||||
- 当前没有单独的导入设置对象;所有默认行为都在 loader 内硬编码。
|
||||
- `.xcvol` header 不通过时会直接失败,不做向后兼容解析。
|
||||
|
||||
## 测试与真实调用点
|
||||
## 公开接口
|
||||
|
||||
- `tests/Resources/Volume/test_volume_field_loader.cpp`
|
||||
- 覆盖 `GetResourceType`
|
||||
- 覆盖 `CanLoad`
|
||||
- 覆盖无效路径加载
|
||||
- 覆盖直接读取 NanoVDB source payload
|
||||
- 覆盖 `AssetDatabase` 生成与复用 `.xcvol` artifact
|
||||
- 覆盖按 `AssetRef` 回读项目体积资源
|
||||
- `engine/src/Core/Asset/AssetDatabase.cpp`
|
||||
- 当前通过 `VolumeFieldLoader` 导入项目体积资源并写出 `.xcvol`
|
||||
- `engine/src/Core/Asset/ResourceManager.cpp`
|
||||
- 当前会注册这条 loader
|
||||
| 接口 | 作用 |
|
||||
|------|------|
|
||||
| `VolumeFieldLoader()` / `~VolumeFieldLoader()` | 创建 / 销毁 loader |
|
||||
| `GetResourceType()` | 返回 `ResourceType::VolumeField` |
|
||||
| `GetSupportedExtensions()` | 声明 `nvdb` / `xcvol` |
|
||||
| `CanLoad(...)` | 判断路径是否可由当前 loader 处理 |
|
||||
| `Load(...)` | 加载 `.nvdb` 或 `.xcvol` |
|
||||
| `GetDefaultSettings()` | 当前固定返回 `nullptr` |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Volume](../Volume.md)
|
||||
- [VolumeField](../VolumeField/VolumeField.md)
|
||||
- [AssetDatabase](../../../Core/Asset/AssetDatabase/AssetDatabase.md)
|
||||
- [ResourceManager](../../../Core/Asset/ResourceManager/ResourceManager.md)
|
||||
- [Resources](../../Resources.md)
|
||||
|
||||
92
docs/plan/API文档目录结构第二轮并行任务板_2026-04-09.md
Normal file
92
docs/plan/API文档目录结构第二轮并行任务板_2026-04-09.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# API 文档目录结构第二轮并行任务板(2026-04-09)
|
||||
|
||||
## 使用规则
|
||||
|
||||
- 每个任务块只允许一个会话领取。
|
||||
- 每个任务块必须同时处理:主页面、所属索引页、交叉链接。
|
||||
- 每完成一个任务块所在阶段,都要先审计,再提交推送。
|
||||
- 如果任务路径命中当前并发热点,先不要直接改。
|
||||
|
||||
## 当前并发热点
|
||||
|
||||
以下源码区域当前已有并发修改,相关文档任务默认标记为 `high-risk`:
|
||||
|
||||
- `editor/src/Viewport/**`
|
||||
- `engine/include/XCEngine/RHI/**`
|
||||
- `engine/include/XCEngine/Rendering/Passes/**`
|
||||
- `engine/include/XCEngine/Rendering/Materials/RenderMaterialResolve.h`
|
||||
- `engine/include/XCEngine/UI/Widgets/UISelectionModel.h`
|
||||
- `engine/include/XCEngine/UI/Widgets/UIDragDropInteraction.h`
|
||||
|
||||
## 任务块
|
||||
|
||||
| ID | 范围 | 目标改动 | 主要路径 | 风险 | 状态 | 领取人 |
|
||||
|----|------|----------|----------|------|------|--------|
|
||||
| `R1` | Rendering / 重复目录归位 | 把旧顶层 `CameraRenderer`、`SceneRenderer`、`CameraRenderRequest`、`SceneRenderRequestPlanner`、`SceneRenderRequestUtils`、`RenderCameraData`、`RenderResourceCache`、`RenderSceneExtractor`、`RenderSceneUtility` 合并到真实子模块位置 | `docs/api/XCEngine/Rendering/**` | `medium` | `pending` | |
|
||||
| `R2` | Rendering / 旧命名残留审计 | 处理 `ObjectIdEncoding`、`ObjectIdPass`、`RenderMaterialUtility`、`VisibleRenderObject`,判定迁移到哪里或删除 | `docs/api/XCEngine/Rendering/**` | `medium` | `pending` | |
|
||||
| `E1` | Editor / 历史失效页清理 | 移除或降级 `XCUIDemoPanel`,修正 `panels.md`、`ImGuiTransitionBackend.md` 等反向链接 | `docs/api/XCEngine/Editor/panels/**` | `low` | `pending` | |
|
||||
| `V1` | Resources / Volume | 建立 `Volume.md`、`VolumeField.md`、`VolumeFieldLoader.md`,同步 `Resources.md` | `docs/api/XCEngine/Resources/Volume/**` | `low` | `pending` | |
|
||||
| `V2` | Components / Volume | 建立 `VolumeRendererComponent.md`,同步 `Components.md` | `docs/api/XCEngine/Components/VolumeRendererComponent/**` | `low` | `pending` | |
|
||||
| `V3` | Rendering / Volume FrameData | 建立 `VisibleVolumeItem.md`,同步 `FrameData.md` | `docs/api/XCEngine/Rendering/FrameData/**` | `low` | `pending` | |
|
||||
| `V4` | Rendering / Volume & Selection Passes | 建立 `BuiltinSelectionMaskPass.md`、`BuiltinSelectionOutlinePass.md`、`BuiltinVolumetricPass.md`,同步 `Passes.md` | `docs/api/XCEngine/Rendering/Passes/**` | `high-risk` | `pending` | |
|
||||
| `U1` | UI / Widgets Helpers | 建立 `UIDragDropInteraction.md`、`UIScrollModel.md`,同步 `Widgets.md` | `docs/api/XCEngine/UI/Widgets/**` | `high-risk` | `pending` | |
|
||||
| `ED1` | Editor / ComponentEditors | 建立 `VolumeRendererComponentEditor.md`,同步 `ComponentEditors.md` | `docs/api/XCEngine/Editor/ComponentEditors/**` | `low` | `pending` | |
|
||||
| `ED2` | Editor / panels Material Authoring | 建立 `MaterialInspectorMaterialState.md`、`MaterialInspectorMaterialStateIO.md`,同步 `panels.md` | `docs/api/XCEngine/Editor/panels/**` | `low` | `pending` | |
|
||||
| `RR1` | RHI 内容回归 | 根据当前真实头文件更新 `RHI*`、`D3D12`、`OpenGL`、`Vulkan` 文档内容与结构 | `docs/api/XCEngine/RHI/**` | `high-risk` | `pending` | |
|
||||
| `RR2` | Rendering / Passes 内容回归 | 根据当前修改中的 builtin pass 头文件更新文档内容与链接 | `docs/api/XCEngine/Rendering/Passes/**` | `high-risk` | `pending` | |
|
||||
| `RR3` | Rendering / Materials 内容回归 | 把 `RenderMaterialResolve` 相关文档与当前头文件重新对齐 | `docs/api/XCEngine/Rendering/Materials/**` | `high-risk` | `pending` | |
|
||||
| `G1` | 全量审计与空目录清理 | 跑审计、清空旧重复目录、清理空目录与错链 | `docs/api/_meta/**`, `docs/api/XCEngine/**` | `medium` | `pending` | |
|
||||
|
||||
## 推荐阶段顺序
|
||||
|
||||
### 第一阶段
|
||||
|
||||
- `R1`
|
||||
- `R2`
|
||||
- `E1`
|
||||
|
||||
这一阶段的目标是先把“结构错位”和“失效历史页”清掉。
|
||||
|
||||
### 第二阶段
|
||||
|
||||
- `V1`
|
||||
- `V2`
|
||||
- `V3`
|
||||
- `ED1`
|
||||
- `ED2`
|
||||
|
||||
这一阶段优先补低冲突、可快速收口的缺页。
|
||||
|
||||
### 第三阶段
|
||||
|
||||
- `V4`
|
||||
- `U1`
|
||||
- `RR1`
|
||||
- `RR2`
|
||||
- `RR3`
|
||||
|
||||
这一阶段等源码波动收敛后再做。
|
||||
|
||||
### 第四阶段
|
||||
|
||||
- `G1`
|
||||
|
||||
## 验收口径
|
||||
|
||||
### 结构验收
|
||||
|
||||
- 每个 API 只保留一个 canonical 目录位置。
|
||||
- 文档目录层级必须与真实源码父目录一致。
|
||||
- 不再允许顶层旧路径和子模块新路径并存。
|
||||
|
||||
### 审计验收
|
||||
|
||||
- `Invalid header refs = 0`
|
||||
- `Invalid source refs = 0`
|
||||
- `Broken .md links = 0`
|
||||
- `Missing directory index pages = 0`
|
||||
|
||||
### 协作验收
|
||||
|
||||
- 每个阶段完成后立即提交推送。
|
||||
- 任务板状态同步更新,避免重复领取。
|
||||
211
docs/plan/API文档目录结构第二轮重构计划_2026-04-09.md
Normal file
211
docs/plan/API文档目录结构第二轮重构计划_2026-04-09.md
Normal file
@@ -0,0 +1,211 @@
|
||||
# API 文档目录结构第二轮重构计划
|
||||
|
||||
## 1. 背景
|
||||
|
||||
项目最近又经历了一轮较大的源码重构,`docs/api/XCEngine` 当前虽然顶层大类仍然存在,但内部已经出现了两类更严重的问题:
|
||||
|
||||
- 目录层级错位:文档页名字还对,但挂在了错误的父目录下。
|
||||
- 新旧结构并存:旧位置和新位置同时保留,导致同一 API 在文档树里出现两套入口。
|
||||
|
||||
这轮重构不再是简单补页,而是要把 `docs/api` 再次拉回到“与实际源码模块结构平行”的状态。
|
||||
|
||||
## 2. 本轮核对基准
|
||||
|
||||
本轮计划基于以下真实代码树做对照:
|
||||
|
||||
- 运行时 public headers:`engine/include/XCEngine/**`
|
||||
- 旧版编辑器 source-backed API:`editor/src/**`
|
||||
- 当前文档树:`docs/api/XCEngine/**`
|
||||
|
||||
同时参考了最新本地审计结果:
|
||||
|
||||
- `python -B docs/api/_tools/audit_api_docs.py`
|
||||
|
||||
## 3. 已确认的结构性问题
|
||||
|
||||
### 3.1 Rendering 存在成对重复目录
|
||||
|
||||
当前已确认以下目录同时出现在“旧顶层位置”和“源码对应的新子模块位置”:
|
||||
|
||||
- `docs/api/XCEngine/Rendering/CameraRenderer`
|
||||
- `docs/api/XCEngine/Rendering/Execution/CameraRenderer`
|
||||
- `docs/api/XCEngine/Rendering/SceneRenderer`
|
||||
- `docs/api/XCEngine/Rendering/Execution/SceneRenderer`
|
||||
- `docs/api/XCEngine/Rendering/CameraRenderRequest`
|
||||
- `docs/api/XCEngine/Rendering/Planning/CameraRenderRequest`
|
||||
- `docs/api/XCEngine/Rendering/SceneRenderRequestPlanner`
|
||||
- `docs/api/XCEngine/Rendering/Planning/SceneRenderRequestPlanner`
|
||||
- `docs/api/XCEngine/Rendering/SceneRenderRequestUtils`
|
||||
- `docs/api/XCEngine/Rendering/Planning/SceneRenderRequestUtils`
|
||||
- `docs/api/XCEngine/Rendering/RenderCameraData`
|
||||
- `docs/api/XCEngine/Rendering/FrameData/RenderCameraData`
|
||||
- `docs/api/XCEngine/Rendering/RenderResourceCache`
|
||||
- `docs/api/XCEngine/Rendering/Caches/RenderResourceCache`
|
||||
- `docs/api/XCEngine/Rendering/RenderSceneExtractor`
|
||||
- `docs/api/XCEngine/Rendering/Extraction/RenderSceneExtractor`
|
||||
- `docs/api/XCEngine/Rendering/RenderSceneUtility`
|
||||
- `docs/api/XCEngine/Rendering/Extraction/RenderSceneUtility`
|
||||
|
||||
这说明文档树里同时保留了“旧的平铺布局”和“新的源码子模块布局”。后续必须只保留源码对应路径,旧路径下的内容要迁移或删除,不能继续并存。
|
||||
|
||||
### 3.2 Rendering 还有一批疑似旧命名/旧抽象残留
|
||||
|
||||
当前已确认下列目录没有直接对应到当前真实头文件命名,属于优先审计对象:
|
||||
|
||||
- `docs/api/XCEngine/Rendering/ObjectIdEncoding`
|
||||
- `docs/api/XCEngine/Rendering/ObjectIdPass`
|
||||
- `docs/api/XCEngine/Rendering/RenderMaterialUtility`
|
||||
- `docs/api/XCEngine/Rendering/VisibleRenderObject`
|
||||
|
||||
这些目录大概率分别对应:
|
||||
|
||||
- 已下沉或改名后的 `Picking/ObjectIdCodec`
|
||||
- `Passes/BuiltinObjectIdPass`
|
||||
- `Materials/RenderMaterialResolve`
|
||||
- `FrameData/VisibleRenderItem`
|
||||
|
||||
但不能直接机械删除,必须先做“旧页内容是否需要迁移”的核对。
|
||||
|
||||
### 3.3 Editor 仍保留已脱离源码的历史页
|
||||
|
||||
当前已确认:
|
||||
|
||||
- `docs/api/XCEngine/Editor/panels/XCUIDemoPanel/XCUIDemoPanel.md`
|
||||
|
||||
对应源码:
|
||||
|
||||
- `editor/src/panels/XCUIDemoPanel.h`
|
||||
- `editor/src/panels/XCUIDemoPanel.cpp`
|
||||
|
||||
这两个文件都已经不存在。
|
||||
|
||||
当前仍引用该历史页的文档包括:
|
||||
|
||||
- `docs/api/XCEngine/Editor/panels/panels.md`
|
||||
- `docs/api/XCEngine/Editor/XCUIBackend/ImGuiTransitionBackend/ImGuiTransitionBackend.md`
|
||||
|
||||
`docs/api/XCEngine/UI/DrawData/DrawData.md` 里已经改成“旧链路说明”,这类描述可以保留,但不应该继续把 `XCUIDemoPanel` 作为真实 canonical API 页面入口。
|
||||
|
||||
### 3.4 审计明确缺页仍然存在
|
||||
|
||||
最新审计仍明确指出以下缺口需要补齐:
|
||||
|
||||
- `XCEngine/Components/VolumeRendererComponent.h`
|
||||
- `XCEngine/Rendering/FrameData/VisibleVolumeItem.h`
|
||||
- `XCEngine/Rendering/Passes/BuiltinSelectionMaskPass.h`
|
||||
- `XCEngine/Rendering/Passes/BuiltinSelectionOutlinePass.h`
|
||||
- `XCEngine/Rendering/Passes/BuiltinVolumetricPass.h`
|
||||
- `XCEngine/Resources/Volume/VolumeField.h`
|
||||
- `XCEngine/Resources/Volume/VolumeFieldLoader.h`
|
||||
- `XCEngine/UI/Widgets/UIDragDropInteraction.h`
|
||||
- `XCEngine/UI/Widgets/UIScrollModel.h`
|
||||
- `editor/src/ComponentEditors/VolumeRendererComponentEditor.h`
|
||||
- `editor/src/panels/MaterialInspectorMaterialState.h`
|
||||
- `editor/src/panels/MaterialInspectorMaterialStateIO.h`
|
||||
|
||||
同时还缺少:
|
||||
|
||||
- `docs/api/XCEngine/Resources/Volume/Volume.md`
|
||||
|
||||
### 3.5 当前存在并发修改热点
|
||||
|
||||
当前工作区里已有其他会话在修改以下源码区域,对应文档重构要么延后,要么单独协调:
|
||||
|
||||
- `editor/src/Viewport/**`
|
||||
- `engine/include/XCEngine/RHI/**`
|
||||
- `engine/include/XCEngine/Rendering/Passes/**`
|
||||
- `engine/include/XCEngine/Rendering/Materials/RenderMaterialResolve.h`
|
||||
- `engine/include/XCEngine/UI/Widgets/UISelectionModel.h`
|
||||
- `engine/include/XCEngine/UI/Widgets/UIDragDropInteraction.h`
|
||||
|
||||
因此本轮执行要按“低冲突优先”组织阶段,避免多个会话同时改同一批文档。
|
||||
|
||||
## 4. 本轮目标
|
||||
|
||||
### 4.1 结构目标
|
||||
|
||||
- `docs/api/XCEngine/**` 内每一个类/模块页都必须与当前真实源码路径平行。
|
||||
- 同一 API 只能保留一个 canonical 位置。
|
||||
- 旧的错位目录必须迁移或移除,不能继续保留作第二入口。
|
||||
|
||||
### 4.2 内容目标
|
||||
|
||||
- 在结构对齐完成后,再逐批做内容重构。
|
||||
- 内容必须基于当前源码与测试,而不是沿用旧说明。
|
||||
|
||||
### 4.3 协作目标
|
||||
|
||||
- 每一批任务都要能被多个会话独立领取。
|
||||
- 每一阶段结束后立即提交并推送,避免长时间悬空。
|
||||
|
||||
## 5. 分阶段执行
|
||||
|
||||
## Phase A:建立新计划与任务板
|
||||
|
||||
- 新开第二轮计划文件
|
||||
- 新开第二轮并行任务板
|
||||
- 标清“当前确定的问题”和“并发风险路径”
|
||||
|
||||
## Phase B:清理已确认的失效历史页
|
||||
|
||||
- 处理 `XCUIDemoPanel`
|
||||
- 修复所有反向链接
|
||||
- 让 `Invalid source refs` 归零
|
||||
|
||||
## Phase C:Rendering 目录结构归位
|
||||
|
||||
- 把所有错位的顶层 Rendering 目录迁移到真实子模块
|
||||
- 合并旧目录里的方法页/细页到正确的新位置
|
||||
- 删除旧顶层重复入口
|
||||
|
||||
## Phase D:补齐审计明确缺页
|
||||
|
||||
- `Resources/Volume`
|
||||
- `Components/VolumeRendererComponent`
|
||||
- `Rendering/VisibleVolumeItem`
|
||||
- `Rendering` 的体积/选择 pass
|
||||
- `UI/Widgets` 新 helper
|
||||
- `Editor` 的体积组件编辑器与材质状态页
|
||||
|
||||
## Phase E:高风险模块内容回归
|
||||
|
||||
在相关源码停止波动后,再处理:
|
||||
|
||||
- `RHI`
|
||||
- `Rendering/Passes`
|
||||
- `Rendering/Materials`
|
||||
- `Editor/Viewport`
|
||||
- `UI/Widgets`
|
||||
|
||||
## Phase F:总回归
|
||||
|
||||
- 全量跑审计
|
||||
- 清理空目录、错链、旧入口
|
||||
- 更新阶段状态并准备下一轮内容重构
|
||||
|
||||
## 6. 本轮优先级判断
|
||||
|
||||
当前最优先的不是继续写新内容,而是先把“错层级”和“重复入口”消掉。否则后面无论哪个会话补文档,都有较高概率继续写到旧路径。
|
||||
|
||||
因此第二轮的第一主战场是:
|
||||
|
||||
- `docs/api/XCEngine/Rendering`
|
||||
|
||||
第二主战场是:
|
||||
|
||||
- `docs/api/XCEngine/Editor` 中仍脱离真实源码的历史页
|
||||
|
||||
第三主战场才是:
|
||||
|
||||
- 审计明确缺页的 Volume / UI / Editor 补齐
|
||||
|
||||
## 7. 阶段收口要求
|
||||
|
||||
每完成一个阶段,必须执行:
|
||||
|
||||
1. 本地核对改动范围
|
||||
2. `python -B docs/api/_tools/audit_api_docs.py`
|
||||
3. `git commit`
|
||||
4. `git push`
|
||||
|
||||
只有在上一阶段已经提交推送后,才进入下一阶段。
|
||||
Reference in New Issue
Block a user