docs(plan): add api doc restructure task board

This commit is contained in:
2026-04-09 23:40:43 +08:00
parent 20b5c22a6a
commit 681452c70e
25 changed files with 898 additions and 15 deletions

View File

@@ -4,7 +4,7 @@
**类型**: `module`
**描述**: 提供 `GameObject`/`Component` 组合式对象模型,以及相机、灯光、网格渲染、音频等场景组件的 public API。
**描述**: 提供 `GameObject`/`Component` 组合式对象模型,以及相机、灯光、网格渲染、体积渲染、音频等场景组件的 public API。
## 概览
@@ -23,7 +23,7 @@
- 生命周期由 `GameObject``Scene` 驱动,运行时直接 `AddComponent<T>()` 并不会自动补发 `Awake``Start``OnEnable`
- 序列化职责分层:`GameObject::Serialize()` 只写对象基础字段和 `Transform`,完整场景保存由 `Scene::SerializeToString()` 负责组件和父子关系。
- `ComponentFactoryRegistry` 只负责把序列化文本里的组件类型名还原为内建组件实例,`Transform` 不走这条路径。
- 渲染组件链路当前是显式拆分的:`MeshFilterComponent` 负责 mesh 的运行时路径缓存、项目 `AssetRef` 与句柄绑定,`MeshRendererComponent` 负责材质槽的运行时路径缓存、项目 `AssetRef`、句柄以及渲染附加状态;对项目资产来说,正式持久化协议都优先是 `AssetRef`,而不是普通项目路径。
- 渲染组件链路当前是显式拆分的:`MeshFilterComponent` 负责 mesh 的运行时路径缓存、项目 `AssetRef` 与句柄绑定,`MeshRendererComponent` 负责材质槽的运行时路径缓存、项目 `AssetRef`、句柄以及渲染附加状态;`VolumeRendererComponent` 则为体对象持有 `VolumeField`、体材质以及阴影参与标记。对项目资产来说,正式持久化协议都优先是 `AssetRef`,而不是普通项目路径。
## 适用场景
@@ -52,13 +52,15 @@
- [LightComponent](LightComponent/LightComponent.md) - `LightComponent.h`,基础灯光参数。
- [MeshFilterComponent](MeshFilterComponent/MeshFilterComponent.md) - `MeshFilterComponent.h`mesh 资源绑定、序列化路径和资产引用恢复。
- [MeshRendererComponent](MeshRendererComponent/MeshRendererComponent.md) - `MeshRendererComponent.h`,材质槽和渲染附加参数。
- [VolumeRendererComponent](VolumeRendererComponent/VolumeRendererComponent.md) - `VolumeRendererComponent.h`,体积资源、体积材质与阴影标志绑定。
- [TransformComponent](TransformComponent/TransformComponent.md) - `TransformComponent.h`,局部/世界变换与层级矩阵。
- [VolumeRendererComponent](VolumeRendererComponent/VolumeRendererComponent.md) - `VolumeRendererComponent.h`,体数据、体材质和阴影标记组件。
## 推荐阅读顺序
1. 先读 [GameObject-Component Lifecycle And Serialization](../../_guides/Components/GameObject-Component-Lifecycle-And-Serialization.md),建立整体心智模型。
2. 再读 [GameObject](GameObject/GameObject.md) 和 [TransformComponent](TransformComponent/TransformComponent.md),理解对象树和变换树的关系。
3. 如果关注渲染资源绑定,再读 [MeshFilterComponent](MeshFilterComponent/MeshFilterComponent.md)[MeshRendererComponent](MeshRendererComponent/MeshRendererComponent.md),理解几何、材质和渲染提取之间的分工。
3. 如果关注渲染资源绑定,再读 [MeshFilterComponent](MeshFilterComponent/MeshFilterComponent.md)[MeshRendererComponent](MeshRendererComponent/MeshRendererComponent.md) 和 [VolumeRendererComponent](VolumeRendererComponent/VolumeRendererComponent.md),理解几何对象、体对象、材质和渲染提取之间的分工。
4. 最后按功能阅读其余组件页,例如 [CameraComponent](CameraComponent/CameraComponent.md)、[AudioSourceComponent](AudioSourceComponent/AudioSourceComponent.md)。
## 相关文档

View File

@@ -0,0 +1,112 @@
# VolumeRendererComponent
**命名空间**: `XCEngine::Components`
**类型**: `class`
**头文件**: `XCEngine/Components/VolumeRendererComponent.h`
**源文件**: `engine/src/Components/VolumeRendererComponent.cpp`
**描述**: 体积渲染组件,负责把 `VolumeField`、体积材质和少量阴影标志绑定到 `GameObject` 上,并在序列化/反序列化与 deferred load 场景中保持资源身份恢复。
## 角色概述
`VolumeRendererComponent` 回答的问题是:
- 这个对象是否要作为体积参与渲染?
- 它绑定的是哪一个 `VolumeField`
- 它使用哪一个 `Material`
- 体积对象当前的阴影开关是什么?
和 [MeshRendererComponent](../MeshRendererComponent/MeshRendererComponent.md) 类似,它同时承担“运行时资源句柄”和“可持久化资源身份”两层职责。
## 当前状态模型
当前实现维护两组几乎对称的资源状态:
| 状态 | 作用 |
|------|------|
| `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` | 阴影相关附加开关。 |
## 绑定与恢复流程
### 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"` 注册为内建组件类型
## 当前实现边界
- 正式持久化协议优先是 `AssetRef`,不是普通项目路径。
- 只有 virtual scheme 路径才会在没有有效 `AssetRef` 时稳定保留。
- 当前组件只维护一个体积资源和一个材质,不涉及更复杂的多体积槽位模型。
## 相关文档
- [当前模块](../Components.md)
- [VolumeField](../../Resources/Volume/VolumeField/VolumeField.md)
- [VisibleVolumeItem](../../Rendering/FrameData/VisibleVolumeItem/VisibleVolumeItem.md)
- [BuiltinVolumetricPass](../../Rendering/Passes/BuiltinVolumetricPass/BuiltinVolumetricPass.md)

View File

@@ -6,7 +6,7 @@
**头文件**: `XCEngine/Rendering/Extraction/RenderSceneExtractor.h`
**描述**: 把 `Scene` 压平成渲染侧可消费的 `RenderSceneData`,负责相机选择、环境与光照提取,以及 `visibleItems` 收集。
**描述**: 把 `Scene` 压平成渲染侧可消费的 `RenderSceneData`,负责相机选择、环境与光照提取,以及网格 `visibleItems` 和体对象 `visibleVolumes` 收集。
## 概览
@@ -25,11 +25,13 @@
- [RenderEnvironmentData](../../FrameData/RenderEnvironmentData/RenderEnvironmentData.md)
- `RenderLightingData`
- `visibleItems`
- `visibleVolumes`
## 当前实现边界
- 当前仍没有 frustum culling、occlusion culling 或 batching。
- 当前光照提取仍以主方向光和 additional lights 快照为主。
- 体对象提取已经进入正式 `RenderSceneData` 主链,但更复杂的 volume-specific culling 或排序策略当前还没有单独拆层。
## 相关文档
@@ -37,4 +39,3 @@
- [RenderSceneUtility](../RenderSceneUtility/RenderSceneUtility.md)
- [RenderSceneData](../../FrameData/RenderSceneData/RenderSceneData.md)
- [CameraRenderer](../../Execution/CameraRenderer/CameraRenderer.md)

View File

@@ -18,6 +18,8 @@
- [RenderEnvironmentData](RenderEnvironmentData/RenderEnvironmentData.md)
- [RenderSceneData](RenderSceneData/RenderSceneData.md)
- [VisibleRenderItem](VisibleRenderItem/VisibleRenderItem.md)
- [VisibleVolumeItem](VisibleVolumeItem/VisibleVolumeItem.md)
- [VisibleVolumeItem](VisibleVolumeItem/VisibleVolumeItem.md)
## 当前职责
@@ -25,6 +27,8 @@
- 承载环境与 skybox 语义
- 承载主方向光、阴影和 additional lights 快照
- 承载 scene extraction 之后的 `visibleItems`
- 承载 scene extraction 之后的 `visibleVolumes`
- 承载 scene extraction 之后的 `visibleVolumes`
## 相关文档
@@ -32,4 +36,3 @@
- [Planning](../Planning/Planning.md)
- [Extraction](../Extraction/Extraction.md)
- [Execution](../Execution/Execution.md)

View File

@@ -6,7 +6,7 @@
**头文件**: `XCEngine/Rendering/FrameData/RenderSceneData.h`
**描述**: scene extraction 之后的核心帧数据块,汇总相机、环境、光照、全局 shader keywords `visibleItems`
**描述**: scene extraction 之后的核心帧数据块,汇总相机、环境、光照、全局 shader keywords、网格 `visibleItems` 与体对象 `visibleVolumes`
## 头文件中的主要类型
@@ -43,6 +43,7 @@
- `lighting`
- `globalShaderKeywords`
- `visibleItems`
- `visibleVolumes`
`HasCamera()` 当前只检查 `camera != nullptr`
@@ -50,7 +51,7 @@
- [RenderSceneExtractor](../../Extraction/RenderSceneExtractor/RenderSceneExtractor.md) 生成 `RenderSceneData`
- [CameraRenderer](../../Execution/CameraRenderer/CameraRenderer.md) 消费它
- builtin pipeline 和各类 pass 从它的 `visibleItems` / lighting / cameraData 继续取数
- builtin pipeline 和各类 pass 从它的 `visibleItems``visibleVolumes`lighting cameraData 继续取数
## 相关文档
@@ -58,5 +59,5 @@
- [RenderCameraData](../RenderCameraData/RenderCameraData.md)
- [RenderEnvironmentData](../RenderEnvironmentData/RenderEnvironmentData.md)
- [VisibleRenderItem](../VisibleRenderItem/VisibleRenderItem.md)
- [VisibleVolumeItem](../VisibleVolumeItem/VisibleVolumeItem.md)
- [RenderSceneExtractor](../../Extraction/RenderSceneExtractor/RenderSceneExtractor.md)

View File

@@ -0,0 +1,43 @@
# VisibleVolumeItem
**命名空间**: `XCEngine::Rendering`
**类型**: `struct`
**头文件**: `XCEngine/Rendering/FrameData/VisibleVolumeItem.h`
**描述**: scene extraction 之后交给体积渲染阶段消费的一条可见体积记录,已经带上体积组件、体积资源、材质、渲染队列、相机距离和世界变换。
## 字段
| 字段 | 说明 |
|------|------|
| `gameObject` | 来源场景对象。 |
| `volumeRenderer` | 提供体积资源与阴影标志的组件。 |
| `volumeField` | 当前解析出的体积资源。 |
| `material` | 当前解析出的材质指针,可为空。 |
| `renderQueue` | 当前体积项的渲染队列。 |
| `cameraDistanceSq` | 到当前相机的距离平方。 |
| `localToWorld` | 当前体积项的世界变换。 |
## 当前语义
- 只有对象上存在有效 [VolumeRendererComponent](../../../Components/VolumeRendererComponent/VolumeRendererComponent.md) 且体积资源可解析时scene extraction 才会生成这条记录。
- opaque / transparent 的排序规则同样会消费 `renderQueue``cameraDistanceSq`
- 这条记录与 [VisibleRenderItem](../VisibleRenderItem/VisibleRenderItem.md) 平行存在,前者服务体积链路,后者服务 mesh 链路。
## 当前调用链
- `engine/src/Rendering/Extraction/RenderSceneUtility.cpp`
- 负责构造 `VisibleVolumeItem`
- `engine/src/Rendering/Extraction/RenderSceneExtractor.cpp`
- 负责提取与排序 `sceneData.visibleVolumes`
- [BuiltinVolumetricPass](../../Passes/BuiltinVolumetricPass/BuiltinVolumetricPass.md)
- 当前消费 `visibleVolumes`
## 相关文档
- [FrameData](../FrameData.md)
- [VisibleRenderItem](../VisibleRenderItem/VisibleRenderItem.md)
- [VolumeRendererComponent](../../../Components/VolumeRendererComponent/VolumeRendererComponent.md)
- [BuiltinVolumetricPass](../../Passes/BuiltinVolumetricPass/BuiltinVolumetricPass.md)

View File

@@ -0,0 +1,30 @@
# BuiltinVolumetricPass::BuildInputLayout
**命名空间**: `XCEngine::Rendering::Passes`
**类型**: `method`
**头文件**: `XCEngine/Rendering/Passes/BuiltinVolumetricPass.h`
## 签名
```cpp
static RHI::InputLayoutDesc BuildInputLayout();
```
## 作用
返回 `BuiltinVolumetricPass` 当前使用的顶点布局描述。
## 当前行为
- 当前布局直接基于 `Resources::StaticMeshVertex`
- 依次声明:
- `POSITION`
- `NORMAL`
- `TEXCOORD0`
- 说明体积 pass 当前复用静态网格顶点结构,而不是定义单独的体积代理顶点格式。
## 相关文档
- [BuiltinVolumetricPass](BuiltinVolumetricPass.md)

View File

@@ -0,0 +1,75 @@
# BuiltinVolumetricPass
**命名空间**: `XCEngine::Rendering::Passes`
**类型**: `class`
**头文件**: `XCEngine/Rendering/Passes/BuiltinVolumetricPass.h`
**描述**: builtin 体积渲染 pass消费 `RenderSceneData::visibleVolumes`,为每个可见体积解析 shader pass、管线状态、descriptor set 与 `VolumeField` GPU 资源后执行绘制。
## 概览
`BuiltinVolumetricPass` 当前是体积渲染进入 builtin forward 链路的实际执行者。它不是独立的体积框架,而是围绕现有 scene-pass 体系补出的一条专用路径:
- 输入来自 `RenderSceneData::visibleVolumes`
- 几何代理当前固定使用 builtin cube mesh
- 资源绑定依赖 shader pass 的 builtin resource layout 解析
- 当前只接受 `VolumeStorageKind::NanoVDB`
## 当前执行流程
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
## 关键资源约束
- 需要单一颜色附件和有效深度附件。
- `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
## 当前实现边界
- pass 本身不负责 scene extraction也不负责决定 `visibleVolumes` 的排序策略。
- 当前代理几何固定为 builtin cube而不是从体数据本身生成裁剪几何。
- 当前 lighting constants 只消费主方向光。
- 资源清理通过 `Shutdown()` / 析构集中处理。
## 公开方法
| 方法 | 说明 |
|------|------|
| [BuildInputLayout](BuildInputLayout.md) | 构建当前体积 pass 使用的顶点布局。 |
| [GetName](GetName.md) | 返回 pass 名称。 |
| [Initialize](Initialize.md) | 预热 device/backend 相关资源。 |
| [Execute](Execute.md) | 遍历 `visibleVolumes` 并提交绘制。 |
| [Shutdown](Shutdown.md) | 销毁缓存的管线、descriptor 与资源状态。 |
## 相关文档
- [Passes](../Passes.md)
- [VisibleVolumeItem](../../FrameData/VisibleVolumeItem/VisibleVolumeItem.md)
- [VolumeField](../../../Resources/Volume/VolumeField/VolumeField.md)
- [VolumeRendererComponent](../../../Components/VolumeRendererComponent/VolumeRendererComponent.md)

View File

@@ -0,0 +1,33 @@
# BuiltinVolumetricPass::Execute
**命名空间**: `XCEngine::Rendering::Passes`
**类型**: `method`
**头文件**: `XCEngine/Rendering/Passes/BuiltinVolumetricPass.h`
## 签名
```cpp
bool Execute(const RenderPassContext& context) override;
```
## 作用
遍历 `visibleVolumes`,为每个可见体积提交一次 volumetric draw。
## 当前行为
- `renderContext` 无效时返回 `false`
- `visibleVolumes` 为空时直接返回 `true`,表示“没有工作但不算失败”。
- 要求:
- 单一颜色附件
- 非空深度附件
- 正常的 `renderArea`
- 会设置 render target、viewport、scissor 和三角形拓扑。
- 最终逐项调用内部 `DrawVisibleVolume(...)`
## 相关文档
- [BuiltinVolumetricPass](BuiltinVolumetricPass.md)
- [VisibleVolumeItem](../../FrameData/VisibleVolumeItem/VisibleVolumeItem.md)

View File

@@ -0,0 +1,25 @@
# BuiltinVolumetricPass::GetName
**命名空间**: `XCEngine::Rendering::Passes`
**类型**: `method`
**头文件**: `XCEngine/Rendering/Passes/BuiltinVolumetricPass.h`
## 签名
```cpp
const char* GetName() const override;
```
## 作用
返回当前 pass 的稳定名称。
## 当前行为
- 固定返回 `"BuiltinVolumetricPass"`
## 相关文档
- [BuiltinVolumetricPass](BuiltinVolumetricPass.md)

View File

@@ -0,0 +1,28 @@
# BuiltinVolumetricPass::Initialize
**命名空间**: `XCEngine::Rendering::Passes`
**类型**: `method`
**头文件**: `XCEngine/Rendering/Passes/BuiltinVolumetricPass.h`
## 签名
```cpp
bool Initialize(const RenderContext& context) override;
```
## 作用
预热当前 device/backend 相关资源。
## 当前行为
- 直接转发到内部 `EnsureInitialized(context)`
- 若 device/backend 变化,旧缓存会先被 `DestroyResources()` 清掉,再重新创建。
- 当前初始化阶段最关键的资源是 builtin cube mesh。
## 相关文档
- [BuiltinVolumetricPass](BuiltinVolumetricPass.md)
- [Shutdown](Shutdown.md)

View File

@@ -0,0 +1,33 @@
# BuiltinVolumetricPass::Shutdown
**命名空间**: `XCEngine::Rendering::Passes`
**类型**: `method`
**头文件**: `XCEngine/Rendering/Passes/BuiltinVolumetricPass.h`
## 签名
```cpp
void Shutdown() override;
```
## 作用
销毁 `BuiltinVolumetricPass` 当前持有的缓存资源。
## 当前行为
- 转发到 `DestroyResources()`
- 会清理:
- `RenderResourceCache`
- 所有 pipeline state
- 所有动态 descriptor set
- 所有 pass resource layout
- builtin cube mesh 句柄
- 最后把 device/backend 状态恢复到初始值。
## 相关文档
- [BuiltinVolumetricPass](BuiltinVolumetricPass.md)
- [Initialize](Initialize.md)

View File

@@ -6,7 +6,7 @@
**头文件**: `XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h`
**描述**: 当前内建的前向主渲染管线实现。它会按 shader pass 的资源声明动态构建 `PassResourceLayout`、descriptor set 与 `RHIPipelineState`,并通过 `RenderPassSequence` 执行默认的 opaque pass
**描述**: 当前内建的前向主渲染管线实现。它会按 shader pass 的资源声明动态构建 `PassResourceLayout`、descriptor set 与 `RHIPipelineState`,并通过 `RenderPassSequence` 顺序执行 opaque、skybox、volumetric 和 transparent 阶段
## 概览
@@ -16,7 +16,14 @@
- `m_pipelineStates`:以 `(shader*, passName, material render state)` 为 key缓存真正的图形 pipeline state。
- `m_dynamicDescriptorSets`:以 `(passLayout, setIndex, objectId, material)` 为 key缓存逐物体或逐材质的 descriptor set。
构造函数`m_passSequence` 注册一个 `BuiltinForwardOpaquePass`。因此当前仍是一条单 pass 的前向路径,但生命周期已经统一收口到 [RenderPassSequence](../../RenderPass/RenderPass.md)。
当前构造函数`m_passSequence` 依次注册:
- `BuiltinForwardOpaquePass`
- `BuiltinForwardSkyboxPass`
- [BuiltinVolumetricPass](../../Passes/BuiltinVolumetricPass/BuiltinVolumetricPass.md)
- `BuiltinForwardTransparentPass`
因此它已经不再是“单 opaque pass”的过渡版前向路径而是一条正式的多阶段 builtin forward sequence。
## 当前资源契约
@@ -52,9 +59,10 @@ binding-plan 解析之后,布局构建阶段还会继续拒绝以下情况:
1. [Initialize](Initialize.md) 通过 `m_passSequence.Initialize(context)` 进入 pass 生命周期。
2. [Render](Render.md) 把 `RenderContext``RenderSurface``RenderSceneData` 打包成 `RenderPassContext`,再交给 `m_passSequence.Execute(...)`
3. `BuiltinForwardOpaquePass` 内部调用 `ExecuteForwardOpaquePass()`,处理 render target 绑定、viewport/scissor、颜色与深度清理以及前后自动状态切换
4. 渲染阶段遍历 `RenderSceneData::visibleItems`,筛出 `BuiltinMaterialPass::ForwardLit` 物体
5. 每个物体都会按当前材质解析 shader/pass获取或创建 pass layout、pipeline state、动态或静态 descriptor set然后写入常量并发出 draw call
3. `BuiltinForwardOpaquePass` 处理主场景 opaque 物体
4. `BuiltinForwardSkyboxPass` 在环境允许时绘制天空盒
5. [BuiltinVolumetricPass](../../Passes/BuiltinVolumetricPass/BuiltinVolumetricPass.md) 遍历 `RenderSceneData::visibleVolumes`,绘制当前已接入的体对象
6. `BuiltinForwardTransparentPass` 再处理透明阶段。
## 当前实现细节
@@ -64,10 +72,11 @@ binding-plan 解析之后,布局构建阶段还会继续拒绝以下情况:
- 逐材质常量优先来自 `ResolveSchemaMaterialConstantPayload(material)` 暴露的 schema-driven payload
如果 view 无效,才回退到内部 `FallbackPerMaterialConstants { baseColorFactor, alphaCutoffParams }`
- 采样器和 1x1 白色 fallback 纹理在初始化后长期复用;具体 `Texture``Mesh` 的 GPU 资源则由 [RenderResourceCache](../../RenderResourceCache/RenderResourceCache.md) 按需上传。
- 体对象阶段当前已经正式接入 [BuiltinVolumetricPass](../../Passes/BuiltinVolumetricPass/BuiltinVolumetricPass.md),因此 `RenderSceneData` 不再只有 `visibleItems` 一条几何主链。
## 当前限制
- 目前只注册了 `BuiltinForwardOpaquePass`,没有透明排序、阴影、延迟渲染或后处理主路径
- 当前虽然已经有 opaque / skybox / volumetric / transparent 四段 sequence但仍不是延迟渲染、RenderGraph 或更通用的多管线框架
- 资源语义是白名单模型,超出 `PerObject / Material / BaseColorTexture / LinearClampSampler` 的声明不会被接受。
- `Render()` 层面不会因为单个物体 `DrawVisibleItem()` 失败而整体返回 `false`;当前调用点仍然以“尽量继续绘制其余物体”为主。

View File

@@ -24,6 +24,8 @@
- [Mesh](Mesh/Mesh.md)
- [Shader](Shader/Shader.md)
- [Texture](Texture/Texture.md)
- [Volume](Volume/Volume.md)
- [Volume](Volume/Volume.md)
## 头文件

View File

@@ -0,0 +1,38 @@
# Volume
**命名空间**: `XCEngine::Resources`
**类型**: `submodule`
**描述**: 体积资源子模块,承载 `VolumeField` 运行时资源对象与 `VolumeFieldLoader``.nvdb` / `.xcvol` 加载链路。
## 概览
该目录与 `XCEngine/Resources/Volume` 对应的 public headers 保持平行,用于承载唯一的 canonical API 文档入口。
当前 `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 可读结构化缓冲。
## 头文件
- [VolumeField](VolumeField/VolumeField.md) - `VolumeField.h`
- [VolumeFieldLoader](VolumeFieldLoader/VolumeFieldLoader.md) - `VolumeFieldLoader.h`
## 相关文档
- [AssetDatabase](../../Core/Asset/AssetDatabase/AssetDatabase.md)
- [ArtifactFormats](../../Core/Asset/ArtifactFormats/ArtifactFormats.md)
- [RenderResourceCache](../../Rendering/RenderResourceCache/RenderResourceCache.md)
- [上级目录](../Resources.md)
- [API 总索引](../../../main.md)

View File

@@ -0,0 +1,67 @@
# VolumeField
**命名空间**: `XCEngine::Resources`
**类型**: `enum + struct + class`
**头文件**: `XCEngine/Resources/Volume/VolumeField.h`
**源文件**: `engine/src/Resources/Volume/VolumeField.cpp`
**描述**: 体积资源对象,保存体积 payload、包围盒、体素尺寸、index bounds 与 grid 元数据,供资源系统、资产导入链路和体积渲染 pass 共同消费。
## 声明概览
| 声明 | 类型 | 说明 |
|------|------|------|
| `VolumeStorageKind` | `enum class` | 当前体积 payload 的存储格式,现阶段主要是 `NanoVDB`。 |
| `VolumeIndexBounds` | `struct` | 体素索引空间的最小/最大坐标范围,并提供 `==` / `!=`。 |
| `VolumeField` | `class` | 运行时体积资源对象。 |
## 当前资源模型
`VolumeField` 继承 `IResource`,因此同时具备两层信息:
- 资源身份
- `name`
- `path`
- `guid`
- `memorySize`
- 体积内容
- `storageKind`
- `bounds`
- `voxelSize`
- `indexBounds`
- `gridType`
- `gridClass`
- 原始 payload
这意味着它不是“只给渲染器看的裸 payload 缓冲”,而是资源系统可缓存、可导入、可按 `AssetRef` 恢复的正式资源对象。
## 创建与读取语义
- `Create(...)` 要求 `payload != nullptr``payloadSize > 0`,否则直接失败。
- 创建成功后会拷贝整份 payload而不是只保存外部指针。
- `GetWorldBounds()` 当前直接返回 `m_bounds`,尚未引入独立的局部/世界体积边界变换语义。
- `GetPayloadData()` / `GetPayloadSize()` 暴露的是当前缓存 payload用于后续 GPU 上传。
## 当前实现边界
- 当前正式声明的存储格式只有 `Unknown``NanoVDB`
- `VolumeField` 自身不负责解析 `.nvdb` 文件格式;格式解析由 [VolumeFieldLoader](../VolumeFieldLoader/VolumeFieldLoader.md) 完成。
- 运行时 `memorySize``UpdateMemorySize()` 基于对象本体、资源身份字符串和 payload 大小估算。
## 测试与调用链
- `tests/Resources/Volume/test_volume_field.cpp`
- 覆盖 `Create(...)` 对 payload、bounds、voxelSize、indexBounds、gridType、gridClass 的保留行为。
- `engine/src/Rendering/Caches/RenderResourceCache.cpp`
- 当前会读取 payload 并把它上传成 GPU 结构化缓冲。
- [BuiltinVolumetricPass](../../../Rendering/Passes/BuiltinVolumetricPass/BuiltinVolumetricPass.md)
- 通过 `RenderResourceCache` 消费 `VolumeField`
## 相关文档
- [Volume](../Volume.md)
- [VolumeFieldLoader](../VolumeFieldLoader/VolumeFieldLoader.md)
- [RenderResourceCache](../../../Rendering/RenderResourceCache/RenderResourceCache.md)

View File

@@ -0,0 +1,18 @@
# VolumeFieldLoader::CanLoad
```cpp
bool CanLoad(const Containers::String& path) const override;
```
按路径扩展名判断当前 loader 是否可处理该资源。
## 当前规则
- 先提取扩展名并转小写
- 仅接受 `nvdb``xcvol`
- 不在这里区分“构建是否启用 NanoVDB”因此 `nvdb` 的真正可加载性仍要到 `Load(...)` 阶段确认
## 相关文档
- [VolumeFieldLoader](VolumeFieldLoader.md)
- [Load](Load.md)

View File

@@ -0,0 +1,11 @@
# VolumeFieldLoader::VolumeFieldLoader
```cpp
VolumeFieldLoader();
```
构造体积资源加载器。当前构造函数不携带额外状态,主要用于满足资源加载器注册与实例化流程。
## 相关文档
- [VolumeFieldLoader](VolumeFieldLoader.md)

View File

@@ -0,0 +1,11 @@
# VolumeFieldLoader::~VolumeFieldLoader
```cpp
~VolumeFieldLoader() override;
```
析构体积资源加载器。当前头文件未暴露需要手工释放的额外成员状态。
## 相关文档
- [VolumeFieldLoader](VolumeFieldLoader.md)

View File

@@ -0,0 +1,11 @@
# VolumeFieldLoader::GetDefaultSettings
```cpp
ImportSettings* GetDefaultSettings() const override;
```
当前固定返回 `nullptr`,说明体积资源加载器还没有公开的独立导入设置对象。
## 相关文档
- [VolumeFieldLoader](VolumeFieldLoader.md)

View File

@@ -0,0 +1,11 @@
# VolumeFieldLoader::GetResourceType
```cpp
ResourceType GetResourceType() const override;
```
返回 `ResourceType::VolumeField`,用于把当前 loader 注册到体积资源类型。
## 相关文档
- [VolumeFieldLoader](VolumeFieldLoader.md)

View File

@@ -0,0 +1,15 @@
# VolumeFieldLoader::GetSupportedExtensions
```cpp
Containers::Array<Containers::String> GetSupportedExtensions() const override;
```
返回当前支持的体积扩展名列表:
- `nvdb`
- `xcvol`
## 相关文档
- [VolumeFieldLoader](VolumeFieldLoader.md)
- [CanLoad](CanLoad.md)

View File

@@ -0,0 +1,32 @@
# VolumeFieldLoader::Load
```cpp
LoadResult Load(const Containers::String& path, const ImportSettings* settings = nullptr) override;
```
读取体积文件并返回 `VolumeField` 资源或错误信息。
## 当前实现流程
1. 忽略 `settings`
2.`CanLoad(...)` 返回 `false`,直接返回 unsupported-format 错误
3. `xcvol`
- 解析 artifact header
- 校验 magic、schema version 与 payload size
- 读取 payload 和边界元数据
4. `nvdb`
- 启用 `XCENGINE_HAS_NANOVDB` 时读取 NanoVDB grid
- 提取 world bounds、voxel size、index bbox、grid type/class
5. 最终统一创建 `VolumeField`
## 关键语义
- `.xcvol` 是引擎规范化后的体积 artifact加载时会做严格头校验。
- `.nvdb` 是源文件输入;如果当前构建未启用 NanoVDB会返回“当前构建不支持”错误而不是静默失败。
- 返回值始终通过 `LoadResult` 表示,成功时内部资源类型为 `VolumeField`
## 相关文档
- [VolumeFieldLoader](VolumeFieldLoader.md)
- [CanLoad](CanLoad.md)
- [VolumeField](../VolumeField/VolumeField.md)

View File

@@ -0,0 +1,65 @@
# VolumeFieldLoader
**命名空间**: `XCEngine::Resources`
**类型**: `class`
**头文件**: `XCEngine/Resources/Volume/VolumeFieldLoader.h`
**源文件**: `engine/src/Resources/Volume/VolumeFieldLoader.cpp`
**描述**: `VolumeField` 资源加载器,负责识别 source `.nvdb` 与 artifact `.xcvol` 路径,并把它们统一转换成 `VolumeField` 资源对象。
## 概览
`VolumeFieldLoader` 当前承载两条正式加载路径:
1. `.xcvol`
- 读取引擎自己的体积 artifact 格式。
2. `.nvdb`
- 在启用 `XCENGINE_HAS_NANOVDB` 时直接读取 NanoVDB source 文件。
因此它既是运行时加载器,也是 `AssetDatabase` 体积导入链路的核心入口。
## 当前加载模型
- `GetSupportedExtensions()` 当前返回 `nvdb``xcvol`
- `CanLoad(...)` 只按扩展名判定,不预先验证文件存在。
- 相对路径会先尝试当前路径;若不存在,再回退到 `ResourceManager::Get().GetResourceRoot()`
- `.xcvol` 路径会读取 `VolumeFieldArtifactHeader`,要求:
- `magic == "XCVOL02"`
- schema 版本匹配
- `payloadSize > 0`
- `.nvdb` 路径在支持 NanoVDB 时会读取 grid metadata并回填
- `bounds`
- `voxelSize`
- `indexBounds`
- `gridType`
- `gridClass`
## 当前实现边界
- 未启用 `XCENGINE_HAS_NANOVDB`source `.nvdb` 会返回 `NanoVDB source-file support is unavailable in this build`
- `GetDefaultSettings()` 当前固定返回 `nullptr`,说明这条导入链路暂时没有独立的 volume import settings 对象。
- 当前 loader 通过 `REGISTER_RESOURCE_LOADER(VolumeFieldLoader)` 注册到资源系统。
## 测试与真实调用点
- `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
## 相关文档
- [Volume](../Volume.md)
- [VolumeField](../VolumeField/VolumeField.md)
- [AssetDatabase](../../../Core/Asset/AssetDatabase/AssetDatabase.md)
- [ResourceManager](../../../Core/Asset/ResourceManager/ResourceManager.md)