docs(rendering): refine outline and volumetric pass docs
This commit is contained in:
@@ -6,76 +6,64 @@
|
||||
|
||||
**头文件**: `XCEngine/Rendering/Passes/BuiltinObjectIdOutlinePass.h`
|
||||
|
||||
**描述**: 内建的全屏后处理 pass,读取 object-id 纹理并把选中对象轮廓或调试 selection mask 合成到当前颜色目标;真正使用哪份 shader 由调用方通过 `shaderPath` 注入。
|
||||
**描述**: 内建的全屏轮廓合成 pass,读取 object-id 纹理并把选中对象轮廓或调试 selection mask 叠加到当前颜色目标;真正使用哪份 shader 由调用方通过 `shaderPath` 注入。
|
||||
|
||||
## 概览
|
||||
|
||||
## 2026-04-10 同步补充
|
||||
|
||||
以下内容以当前 `BuiltinObjectIdOutlinePass.h/.cpp` 为准:
|
||||
|
||||
- `Render(...)` 的输入不再是裸 `objectIdTextureView` 指针,而是
|
||||
[ObjectIdOutlinePassInputs](../ObjectIdOutlinePassInputs/ObjectIdOutlinePassInputs.md);
|
||||
这让调用方可以同时声明 object-id 纹理在进入 pass 前的资源状态。
|
||||
- `EnsureInitialized(...)` / `CreateResources(...)` 现在按 backend、目标颜色格式和目标 `sampleCount` 重新建资源;当 surface 配置变化时会销毁旧的 pipeline / descriptor 重新创建。
|
||||
- viewport / scissor 已经按 `surface.GetRenderArea()` 取值,不再固定覆盖整张 surface。
|
||||
- 当 `surface.IsAutoTransitionEnabled()` 为 `true` 时,pass 会把目标颜色从 `surface.GetColorStateAfter()` 切到 `RenderTarget`,并把 object-id 纹理从 `inputs.objectIdTextureState` 切到 `PixelShaderResource`,结束后再恢复。
|
||||
|
||||
`BuiltinObjectIdOutlinePass` 处在“object-id 已经生成,但主场景也已经画完”的阶段。它本身不负责提取可见物体,也不负责生成 object-id 纹理,而是消费这些上游结果:
|
||||
|
||||
- object-id 纹理通常来自 `BuiltinObjectIdPass`。
|
||||
- 选中对象列表和 style 当前通常由 editor 侧的 Scene View render plan 提供。
|
||||
- 调用时机当前由 `editor/src/Viewport/Passes/SceneViewportSelectionOutlinePass.cpp` 这类包装 pass 决定,并最终通过 [CameraRenderer](../../Execution/CameraRenderer/CameraRenderer.md) 的 `postScenePasses` 提交。
|
||||
- object-id 纹理通常来自 `BuiltinObjectIdPass`
|
||||
- 选中对象列表和样式通常由 editor 侧 Scene View render plan 提供
|
||||
- 调用时机通常由 `SceneViewportSelectionOutlinePass` 这类包装逻辑决定,并最终通过 [CameraRenderer](../../Execution/CameraRenderer/CameraRenderer.md) 的 `postScenePasses` 提交
|
||||
|
||||
因此它更接近一个“builtin selection feedback compositor”,而不是一个通用 post-process 框架。
|
||||
因此它更接近一个“selection feedback compositor”,而不是通用 post-process 框架。
|
||||
|
||||
和早期实现不同,当前类已经不再把 outline shader 写死为 engine builtin 资源。源码里的职责边界是:
|
||||
和早期实现不同,当前类不再把 outline shader 写死成某个单一后端资源,也不再直接接受裸 `objectIdTextureView` 参数。源码里的职责边界已经变成:
|
||||
|
||||
- `BuiltinObjectIdOutlinePass`
|
||||
只负责资源创建、object-id 采样、常量编码和一次全屏三角形执行。
|
||||
- editor 调用方
|
||||
通过 [SetShaderPath](SetShaderPath.md) 或构造函数参数注入具体 shader 路径。
|
||||
- `SceneViewportSelectionOutlinePass`
|
||||
当前用 [SceneViewportResourcePaths](../../../Editor/Viewport/SceneViewportResourcePaths/SceneViewportResourcePaths.md)
|
||||
生成 editor-owned object-id outline shader 路径,再交给这里执行;`SceneViewportShaderPaths` 只是兼容 include 层。
|
||||
只负责资源创建、选中对象编码、object-id 采样和一次全屏三角形执行
|
||||
- [ObjectIdOutlinePassInputs](../ObjectIdOutlinePassInputs/ObjectIdOutlinePassInputs.md)
|
||||
描述 object-id 纹理视图及其进入 pass 前的资源状态
|
||||
- editor / 调用方
|
||||
通过 [SetShaderPath](SetShaderPath.md) 或构造函数参数注入具体 shader 路径,并负责准备选中对象列表
|
||||
|
||||
## 输入与输出契约
|
||||
|
||||
| 输入 / 输出 | 当前要求 |
|
||||
|------|------|
|
||||
| `renderContext` | 必须有效,且后端类型必须是 `D3D12`。 |
|
||||
| `surface` | 至少要有一个有效的颜色附件;pass 只写 `colorAttachments[0]`。 |
|
||||
| `objectIdTextureView` | 不能为空,并且调用方要保证它已经处于可作为 SRV 读取的状态。 |
|
||||
| `selectedObjectIds` | 不能为空;超过 `256` 个时只会取前 `256` 个。 |
|
||||
| `renderContext` | 必须有效。 |
|
||||
| `surface` | 必须具备恰好一个有效颜色附件,且 render area 有效;pass 只写 `colorAttachments[0]`。 |
|
||||
| `inputs` | 由 [ObjectIdOutlinePassInputs](../ObjectIdOutlinePassInputs/ObjectIdOutlinePassInputs.md) 描述;`objectIdTextureView` 不能为空。 |
|
||||
| `selectedObjectIds` | 运行时对象 ID 列表;最多编码前 `256` 个,且至少要有一个能成功转换成 render object id。 |
|
||||
| `style` | 决定轮廓颜色、宽度和是否改为输出 debug mask。 |
|
||||
| 输出 | 在主颜色目标上 alpha 混合轮廓,或在 debug 模式下输出黑白 selection mask。 |
|
||||
| 输出 | 在主颜色目标上合成轮廓,或在 debug 模式下输出 selection mask 可视化结果。 |
|
||||
|
||||
## 当前渲染算法
|
||||
## 当前渲染流程
|
||||
|
||||
按 `BuiltinObjectIdOutlinePass.cpp` 与当前配置 shader 的实现,流程是:
|
||||
|
||||
1. 校验上下文、后端、object-id SRV 和选中对象列表。
|
||||
2. 懒初始化内部资源,必要时重新创建 pipeline layout、pipeline state 和两个 descriptor set;这一步要求 `shaderPath` 非空且可成功加载。
|
||||
3. 从 `surface.GetWidth()` / `GetHeight()` 计算视口尺寸与 texel size。
|
||||
4. 用 `EncodeObjectIdToColor()` 把选中对象 ID 编码进常量缓冲,最多写入 `kMaxSelectedObjectCount = 256` 项。
|
||||
5. 绑定一个 CBV set 和一个 SRV set,设置目标为 `surface` 的第一个颜色附件。
|
||||
6. 以全屏三角形方式执行 `Draw(3, 1, 0, 0)`。
|
||||
1. 校验 `renderContext`、`inputs.objectIdTextureView`、`selectedObjectIds` 和目标 `surface`
|
||||
2. 通过 `EnsureInitialized(renderContext, surface)` 懒创建或重建 pipeline layout、pipeline state 和两个 descriptor set
|
||||
3. 把运行时对象 ID 转成 render object id,并最多写入 `kMaxSelectedObjectCount = 256` 项编码颜色
|
||||
4. 把常量缓冲写到 `m_constantSet`,把 `inputs.objectIdTextureView` 写到 `m_textureSet`
|
||||
5. 若 `surface` 开启自动状态切换,则把输出颜色附件和 object-id 纹理切到本 pass 需要的状态,并在结束后恢复
|
||||
6. 以 `surface.GetRenderArea()` 作为 viewport/scissor,执行一次全屏三角形 `Draw(3, 1, 0, 0)`
|
||||
|
||||
## 生命周期
|
||||
|
||||
- [Constructor](Constructor.md) 只做状态清零,不会立刻创建 GPU 资源。
|
||||
- [SetShaderPath](SetShaderPath.md) 更新路径时,会立刻销毁当前缓存的 RHI 资源,等待下一次 `Render()` 重新初始化。
|
||||
- 第一次 [Render](Render.md) 成功进入初始化路径时,才会真正创建 descriptor 和 PSO。
|
||||
- [Shutdown](Shutdown.md) 会显式销毁所有内部缓存对象。
|
||||
- [Destructor](Destructor.md) 当前是默认析构,因此如果把它作为长期 renderer 成员使用,调用方仍需在销毁前显式执行 `Shutdown()`。
|
||||
- [Constructor](Constructor.md) 只初始化状态,不会立刻创建 GPU 资源
|
||||
- [SetShaderPath](SetShaderPath.md) 更新路径时,会销毁当前缓存的 RHI 资源,等待下一次 [Render](Render.md) 重新初始化
|
||||
- 第一次成功进入初始化路径时,才会真正创建 descriptor set 和 PSO
|
||||
- [Shutdown](Shutdown.md) 会显式销毁所有内部缓存对象
|
||||
- [Destructor](Destructor.md) 当前仍是默认析构,因此把它作为长期 renderer 成员使用时,调用方仍应在销毁前显式执行 `Shutdown()`
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 只接受 `D3D12`,其它后端直接返回 `false`。
|
||||
- 在第一次创建资源前必须先提供有效 `shaderPath`;空路径会记录错误并返回 `false`。
|
||||
- 不处理资源状态切换,也不负责清屏;这些由调用方保证。
|
||||
- 当前完全忽略 `surface.GetRenderArea()`,viewport 和 scissor 都直接取整张 surface 的宽高。
|
||||
- 只使用第一个颜色附件;多 render target 场景不会同步写其它附件。
|
||||
- 当前不再硬编码限定 `D3D12`;只要配置 shader 在当前 backend 上存在兼容 graphics variant,即可建立资源并执行
|
||||
- 在第一次创建资源前必须先提供有效 `shaderPath`
|
||||
- 只处理单颜色附件输出,不写深度
|
||||
- 当 `surface.IsAutoTransitionEnabled()` 为 `false` 时,pass 不会替调用方检查或修正目标与输入纹理的资源状态
|
||||
- pipeline 资源会按 backend、render target format 和 sample count 重新建立;当前未把 sample quality 纳入该类自身的缓存键
|
||||
|
||||
## 公开方法
|
||||
|
||||
@@ -86,21 +74,19 @@
|
||||
| [SetShaderPath](SetShaderPath.md) | 更新当前要加载的 shader 路径,并清空已创建资源。 |
|
||||
| [GetShaderPath](GetShaderPath.md) | 返回当前记录的 shader 路径。 |
|
||||
| [Shutdown](Shutdown.md) | 销毁已创建的 pipeline、descriptor 和 shader handle。 |
|
||||
| [Render](Render.md) | 读取 object-id SRV,并把轮廓或 debug mask 写入颜色目标。 |
|
||||
| [Render](Render.md) | 读取 object-id 输入,并把轮廓或 debug mask 写入颜色目标。 |
|
||||
|
||||
## 真实使用位置
|
||||
|
||||
- `editor/src/Viewport/Passes/SceneViewportSelectionOutlinePass.cpp` 用 `SceneViewportSelectionOutlinePassRenderer` 包装它,
|
||||
并通过 `GetSceneViewportObjectIdOutlineShaderPath()` 注入 editor-owned shader 路径。
|
||||
- [SceneViewportRenderPlan](../../../Editor/Viewport/SceneViewportRenderPlan/SceneViewportRenderPlan.md) 决定当前帧是否要创建 selection outline pass。
|
||||
- [CameraRenderer](../../Execution/CameraRenderer/CameraRenderer.md) 在主场景与 object-id pass 之后执行这些 `postScenePasses`。
|
||||
- `editor/src/Viewport/ViewportHostRenderFlowUtils.h` 当前为 Scene View 组装默认橙色、`2px` 的 outline style。
|
||||
- `editor/src/Viewport/Passes/SceneViewportSelectionOutlinePass.cpp` 当前会包装它,并通过 `GetSceneViewportObjectIdOutlineShaderPath()` 注入 editor-owned shader 路径
|
||||
- [SceneViewportRenderPlan](../../../Editor/Viewport/SceneViewportRenderPlan/SceneViewportRenderPlan.md) 决定当前帧是否创建 object-id outline 链路
|
||||
- [CameraRenderer](../../Execution/CameraRenderer/CameraRenderer.md) 在主场景与 object-id pass 之后执行这些 `postScenePasses`
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Passes](../Passes.md)
|
||||
- [SetShaderPath](SetShaderPath.md)
|
||||
- [GetShaderPath](GetShaderPath.md)
|
||||
- [Render](Render.md)
|
||||
- [ObjectIdOutlinePassInputs](../ObjectIdOutlinePassInputs/ObjectIdOutlinePassInputs.md)
|
||||
- [ObjectIdOutlineStyle](../ObjectIdOutlineStyle/ObjectIdOutlineStyle.md)
|
||||
- [CameraRenderer](../../Execution/CameraRenderer/CameraRenderer.md)
|
||||
- [RenderSurface](../../RenderSurface/RenderSurface.md)
|
||||
|
||||
@@ -1,23 +1,5 @@
|
||||
# BuiltinObjectIdOutlinePass::Render
|
||||
|
||||
> 2026-04-10 同步:当前签名与语义如下;若下文旧段落仍出现旧的 `objectIdTextureView` 单参数写法,请以这里为准。
|
||||
|
||||
```cpp
|
||||
bool Render(
|
||||
const RenderContext& renderContext,
|
||||
const RenderSurface& surface,
|
||||
const ObjectIdOutlinePassInputs& inputs,
|
||||
const std::vector<uint64_t>& selectedObjectIds,
|
||||
const ObjectIdOutlineStyle& style = {});
|
||||
```
|
||||
|
||||
## 当前语义更新
|
||||
|
||||
- object-id 输入纹理由 [ObjectIdOutlinePassInputs](../ObjectIdOutlinePassInputs/ObjectIdOutlinePassInputs.md) 描述,同时显式携带进入 pass 前的资源状态。
|
||||
- `EnsureInitialized(...)` 现在按 backend、目标颜色格式和目标 `sampleCount` 重新建资源;surface 变化时会销毁旧的 pipeline / descriptor 再创建。
|
||||
- viewport 和 scissor 取自 `surface.GetRenderArea()`,不再固定使用整张 surface。
|
||||
- 当 `surface.IsAutoTransitionEnabled()` 为 `true` 时,会把目标颜色从 `surface.GetColorStateAfter()` 切到 `RenderTarget`,并把 `inputs.objectIdTextureView` 从 `inputs.objectIdTextureState` 切到 `PixelShaderResource`,结束后再恢复。
|
||||
|
||||
**命名空间**: `XCEngine::Rendering::Passes`
|
||||
|
||||
**类型**: `method`
|
||||
@@ -30,7 +12,7 @@ bool Render(
|
||||
bool Render(
|
||||
const RenderContext& renderContext,
|
||||
const RenderSurface& surface,
|
||||
RHI::RHIResourceView* objectIdTextureView,
|
||||
const ObjectIdOutlinePassInputs& inputs,
|
||||
const std::vector<uint64_t>& selectedObjectIds,
|
||||
const ObjectIdOutlineStyle& style = {});
|
||||
```
|
||||
@@ -41,20 +23,22 @@ bool Render(
|
||||
|
||||
## 当前实现流程
|
||||
|
||||
1. 如果 `renderContext` 无效、后端不是 `D3D12`、`objectIdTextureView == nullptr` 或 `selectedObjectIds` 为空,直接返回 `false`。
|
||||
2. 调用 `EnsureInitialized(renderContext)`;如果当前 device/backend 变化,会先销毁旧资源再重建。若 `shaderPath` 为空或配置路径下的 shader 无法加载,也会在这里失败。
|
||||
3. 检查 `surface.GetColorAttachments()`,要求至少存在一个有效颜色附件。
|
||||
4. 构建 `OutlineConstants`,写入 viewport 尺寸、轮廓颜色、调试开关、像素宽度和最多 `256` 个选中对象编码颜色。
|
||||
5. 把常量缓冲写到 `m_constantSet`,把 `objectIdTextureView` 绑定到 `m_textureSet`。
|
||||
6. 设置渲染目标为 `surface` 的第一个颜色附件,并提交一次全屏三角形 `Draw(3, 1, 0, 0)`。
|
||||
1. 如果 `renderContext` 无效、`inputs.objectIdTextureView == nullptr` 或 `selectedObjectIds` 为空,直接返回 `false`。
|
||||
2. 检查 `surface` 是否具备单个有效颜色附件,以及有效的 `renderArea`。
|
||||
3. 调用 `EnsureInitialized(renderContext, surface)`;如果当前 device/backend、render target format 或 sample count 变化,会先销毁旧资源再重建。
|
||||
4. 把 `selectedObjectIds` 逐个转换成 render object id;最多编码 `256` 个,转换失败的条目会被跳过;若最终一个都没留下,返回 `false`。
|
||||
5. 构建 `OutlineConstants`,写入 viewport 尺寸、轮廓颜色、调试开关、像素宽度和选中对象编码颜色。
|
||||
6. 把常量缓冲写到 `m_constantSet`,把 `inputs.objectIdTextureView` 绑定到 `m_textureSet`。
|
||||
7. 若 `surface.IsAutoTransitionEnabled()` 为 `true`,则把输出颜色附件切到 `RenderTarget`、把 object-id 输入从 `inputs.objectIdTextureState` 切到 `PixelShaderResource`,并在结束后恢复。
|
||||
8. 使用 `surface.GetRenderArea()` 设置 viewport 与 scissor,提交一次全屏三角形 `Draw(3, 1, 0, 0)`。
|
||||
|
||||
## 关键语义
|
||||
|
||||
- 这条路径不再隐式依赖 engine builtin outline shader;调用方必须先通过构造函数或 [SetShaderPath](SetShaderPath.md) 提供有效路径。
|
||||
- 这条路径不再隐式依赖某个固定后端 outline shader;调用方必须先通过构造函数或 [SetShaderPath](SetShaderPath.md) 提供有效路径。
|
||||
- 当前只使用 `surface` 的第一个颜色附件。
|
||||
- pass 自己不会做 render target 清空;如果要输出 debug mask 这种“整张替换”的结果,需要由调用方先清空目标。
|
||||
- pass 自己也不负责资源状态切换;调用前应保证颜色目标已经在 `RenderTarget` 状态、object-id SRV 已经可读。
|
||||
- 当前 viewport 和 scissor 始终覆盖整张 surface,而不是 `surface.GetRenderArea()`。
|
||||
- pass 自己不会做 render target 清空;如果要输出 debug mask 这类“整张替换”的结果,需要由调用方先清空目标。
|
||||
- 当自动状态切换关闭时,pass 不会替调用方检查目标与 object-id 输入是否已经处于正确资源状态。
|
||||
- viewport 和 scissor 当前都会遵循 `surface.GetRenderArea()`。
|
||||
|
||||
## 典型使用位置
|
||||
|
||||
@@ -65,5 +49,6 @@ bool Render(
|
||||
|
||||
- [BuiltinObjectIdOutlinePass](BuiltinObjectIdOutlinePass.md)
|
||||
- [SetShaderPath](SetShaderPath.md)
|
||||
- [ObjectIdOutlinePassInputs](../ObjectIdOutlinePassInputs/ObjectIdOutlinePassInputs.md)
|
||||
- [ObjectIdOutlineStyle](../ObjectIdOutlineStyle/ObjectIdOutlineStyle.md)
|
||||
- [RenderSurface](../../RenderSurface/RenderSurface.md)
|
||||
|
||||
@@ -10,30 +10,22 @@
|
||||
|
||||
## 概览
|
||||
|
||||
## 2026-04-10 同步补充
|
||||
|
||||
以下内容以当前 `BuiltinVolumetricPass.h/.cpp` 为准:
|
||||
|
||||
- 新增了公开预热接口 [PrepareVolumeResources](PrepareVolumeResources.md),用于在真正 `Execute(...)` 之前把 cube proxy mesh 和可见 `NanoVDB` volume 的 GPU 资源准备好。
|
||||
- pipeline cache key 现在显式包含目标 surface 的 `sampleCount` 与 `sampleQuality`,不再只按 render state、shader、format 和 keyword 签名区分。
|
||||
- `Execute(...)` 仍要求 surface 具备“单颜色附件 + depth 附件”,但 viewport / scissor 现在按 `surface.GetRenderArea()` 生效。
|
||||
- volume 字段的真实上传与缓存复用由 `RenderResourceCache` 负责;`BuiltinVolumetricPass` 自己不做 legacy fallback。
|
||||
|
||||
`BuiltinVolumetricPass` 是当前体积渲染链路的核心执行器。
|
||||
它继承自 `RenderPass`,但和普通 mesh pass 相比有几处明显特点:
|
||||
|
||||
- 几何始终来自 builtin cube mesh,而不是体积资源自带网格
|
||||
- 着色器必须声明 `PerObject` 与 `VolumeField` 资源绑定
|
||||
- descriptor set 与 pipeline state 会按 shader pass、材质和 volume SRV 动态缓存
|
||||
- descriptor set 与 pipeline state 会按 shader pass、材质、surface 格式以及采样参数动态缓存
|
||||
|
||||
## 当前执行流程
|
||||
|
||||
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
|
||||
1. [Initialize](Initialize.md) / `EnsureInitialized(...)` 加载 builtin cube mesh 和基础资源
|
||||
2. [PrepareVolumeResources](PrepareVolumeResources.md) 预热当前帧可见体积需要的 mesh / volume GPU 资源
|
||||
3. [Execute](Execute.md) 校验 `RenderSurface` 是否具备单颜色附件、深度附件和有效 render area
|
||||
4. 逐个遍历 `sceneData.visibleVolumes`
|
||||
5. 为每个体积解析兼容的 volumetric shader pass
|
||||
6. 构建或复用 pipeline layout、pipeline state 和动态 descriptor set
|
||||
7. 把体积 bounds、材质常量、光照常量与 volume SRV 绑定后提交 draw
|
||||
|
||||
## 关键内部状态
|
||||
|
||||
@@ -42,15 +34,16 @@
|
||||
| `m_builtinCubeMesh` | 所有体积绘制共用的 cube proxy mesh |
|
||||
| `m_resourceCache` | 复用 mesh 与 volume GPU 资源 |
|
||||
| `m_passResourceLayouts` | 按 shader/pass 缓存资源布局 |
|
||||
| `m_pipelineStates` | 按 render state、shader、格式与 keyword 签名缓存 pipeline |
|
||||
| `m_pipelineStates` | 按 render state、shader、格式、sample count / quality 与 keyword 签名缓存 pipeline |
|
||||
| `m_dynamicDescriptorSets` | 按对象、材质、volume field 缓存动态描述符集 |
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 只处理 `VisibleVolumeItem`
|
||||
- 只接受 `VolumeStorageKind::NanoVDB`
|
||||
- 当前只为 `VolumeStorageKind::NanoVDB` 体积准备 GPU 资源并参与绘制
|
||||
- 当前要求 surface 为“单颜色附件 + 深度附件”模型
|
||||
- 若 shader pass 未声明 `PerObject` 或 `VolumeField` 绑定,会直接失败而不是做 legacy fallback
|
||||
- 这仍然是 builtin forward 链路中的一个 scene pass,不是独立的体渲染框架或 render graph 子系统
|
||||
|
||||
## 公开方法
|
||||
|
||||
@@ -58,14 +51,20 @@
|
||||
|------|------|
|
||||
| [BuildInputLayout](BuildInputLayout.md) | 返回体积 pass 使用的顶点布局 |
|
||||
| [GetName](GetName.md) | 返回 pass 名称 |
|
||||
| [Initialize](Initialize.md) | 预热 builtin cube mesh 等资源 |
|
||||
| [PrepareVolumeResources](PrepareVolumeResources.md) | 预热可见体渲染所需的 mesh / volume GPU 资源 |
|
||||
| [Initialize](Initialize.md) | 预热 builtin cube mesh 等基础资源 |
|
||||
| [PrepareVolumeResources](PrepareVolumeResources.md) | 为当前帧可见体积预热 mesh 与 volume GPU 资源 |
|
||||
| [Execute](Execute.md) | 绘制所有可见体积 |
|
||||
| [Shutdown](Shutdown.md) | 销毁缓存的 RHI 资源 |
|
||||
|
||||
## 真实接入位置
|
||||
|
||||
- [BuiltinForwardPipeline](../../Pipelines/BuiltinForwardPipeline/BuiltinForwardPipeline.md) 在场景存在 `visibleVolumes` 时,会先调用 [PrepareVolumeResources](PrepareVolumeResources.md) 预热资源,再把当前 pass 放进 scene-pass 执行序列
|
||||
- `RenderSceneExtractor` 负责把体积对象提取到 `sceneData.visibleVolumes`
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Passes](../Passes.md)
|
||||
- [VisibleVolumeItem](../../FrameData/VisibleVolumeItem/VisibleVolumeItem.md)
|
||||
- [VolumeField](../../../Resources/Volume/VolumeField/VolumeField.md)
|
||||
- [RenderResourceCache](../../Caches/RenderResourceCache/RenderResourceCache.md)
|
||||
- [VolumeRendererComponent](../../../Components/VolumeRendererComponent/VolumeRendererComponent.md)
|
||||
|
||||
@@ -4,28 +4,26 @@
|
||||
bool Execute(const RenderPassContext& context) override;
|
||||
```
|
||||
|
||||
## 2026-04-10 更新
|
||||
|
||||
- `Execute(...)` 现在依赖 surface 的 `renderArea`、`sampleCount` 和 `sampleQuality` 契约;这些字段会进入 pipeline 选择与 viewport/scissor 设置。
|
||||
- volume 数据上传不是在这里兜底完成的;更推荐在前置阶段调用 [PrepareVolumeResources](PrepareVolumeResources.md) 先把 mesh / volume cache 预热好。
|
||||
|
||||
把 `context.sceneData.visibleVolumes` 中的体积绘制到当前 render target。
|
||||
|
||||
## 当前实现流程
|
||||
|
||||
1. 校验 `renderContext`
|
||||
2. 若 `visibleVolumes` 为空,直接返回 `true`
|
||||
3. 要求 surface 具备单颜色附件、深度附件和有效 render area
|
||||
4. 设置 viewport、scissor 和 triangle-list topology
|
||||
5. 逐个调用内部 `DrawVisibleVolume(...)`
|
||||
1. 校验 `renderContext`。
|
||||
2. 若 `visibleVolumes` 为空,直接返回 `true`。
|
||||
3. 要求 surface 具备单颜色附件、深度附件和有效 render area。
|
||||
4. 调用 [PrepareVolumeResources](PrepareVolumeResources.md) 预热当前帧体积资源。
|
||||
5. 设置 viewport、scissor 和 triangle-list topology。
|
||||
6. 逐个调用内部 `DrawVisibleVolume(...)`。
|
||||
|
||||
## 关键语义
|
||||
|
||||
- 这里不负责 scene extraction;输入必须已经是 `VisibleVolumeItem`
|
||||
- 体积绘制依赖材质 shader pass 与 volume SRV 都已可用
|
||||
- 某个体积绘制失败不会自动切换为其他 shader 或 fallback path
|
||||
- 这里不负责 scene extraction;输入必须已经是 `VisibleVolumeItem`。
|
||||
- 体积绘制依赖材质 shader pass 与 volume SRV 都已可用。
|
||||
- pipeline state 会按 surface 的颜色/深度格式与 sample count / quality 建立或复用。
|
||||
- 某个体积绘制失败不会自动切换为其他 shader 或 fallback path。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [BuiltinVolumetricPass](BuiltinVolumetricPass.md)
|
||||
- [PrepareVolumeResources](PrepareVolumeResources.md)
|
||||
- [VisibleVolumeItem](../../FrameData/VisibleVolumeItem/VisibleVolumeItem.md)
|
||||
|
||||
@@ -4,20 +4,17 @@
|
||||
bool Initialize(const RenderContext& context) override;
|
||||
```
|
||||
|
||||
## 2026-04-10 更新
|
||||
|
||||
- `Initialize(...)` 当前仍只是进入内部 `EnsureInitialized(...)`,重点是预热 builtin cube mesh 等基础资源。
|
||||
- 可见 volume 的 GPU 资源预热已经拆到 [PrepareVolumeResources](PrepareVolumeResources.md);如果要在真正绘制前确保 `NanoVDB` 数据和 SRV 就绪,应调用那个入口。
|
||||
|
||||
预热体积 pass 依赖的基础资源。
|
||||
|
||||
## 当前行为
|
||||
|
||||
- 实际入口会转到内部 `EnsureInitialized(...)`
|
||||
- 当前最关键的初始化工作是加载 builtin cube mesh
|
||||
- 若 `RenderContext` 无效或 cube mesh 加载失败,返回 `false`
|
||||
- 实际入口会转到内部 `EnsureInitialized(...)`。
|
||||
- 当前最关键的初始化工作是加载 builtin cube mesh,并准备与 `RenderContext` 绑定的基础缓存。
|
||||
- 这里不会为某一帧具体的 `visibleVolumes` 预热 GPU 资源;这部分工作已经拆到 [PrepareVolumeResources](PrepareVolumeResources.md)。
|
||||
- 若 `RenderContext` 无效或 cube mesh 加载失败,返回 `false`。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [BuiltinVolumetricPass](BuiltinVolumetricPass.md)
|
||||
- [PrepareVolumeResources](PrepareVolumeResources.md)
|
||||
- [Execute](Execute.md)
|
||||
|
||||
@@ -6,22 +6,29 @@ bool PrepareVolumeResources(
|
||||
const RenderSceneData& sceneData);
|
||||
```
|
||||
|
||||
在真正 `Execute(...)` 之前预热体渲染依赖的 mesh / volume GPU 资源。
|
||||
为当前帧可见体积预热 `BuiltinVolumetricPass` 需要的 mesh 与 volume GPU 资源。
|
||||
|
||||
## 当前行为
|
||||
## 当前实现流程
|
||||
|
||||
- 会先确保 builtin cube mesh 的基础资源已经初始化完成。
|
||||
- 当 `sceneData.visibleVolumes` 非空时,会先通过 `RenderResourceCache` 取到 cube proxy mesh 的缓存视图。
|
||||
- 遍历可见体积时,只会继续处理同时满足以下条件的项:
|
||||
- `volumeField != nullptr`
|
||||
- `material != nullptr`
|
||||
- `volumeField->GetStorageKind() == VolumeStorageKind::NanoVDB`
|
||||
- 对于满足条件的体积,会调用 `RenderResourceCache::GetOrCreateVolumeField(...)` 预热 volume SRV;如果缓存创建失败,返回 `false`。
|
||||
- 如果没有可见体积,或所有可见体积都被过滤掉,函数仍然可以返回 `true`。
|
||||
1. 先调用内部 `EnsureInitialized(context)`,确保 builtin cube mesh 等基础资源可用。
|
||||
2. 如果 `visibleVolumes` 非空,则先通过 `RenderResourceCache` 取得 cube proxy mesh 的 GPU 缓存,并要求 `vertexBufferView` 有效。
|
||||
3. 逐个遍历 `sceneData.visibleVolumes`。
|
||||
4. 对同时满足“存在 `volumeField`、存在 `material`、且存储类型为 `NanoVDB`”的条目,调用 `RenderResourceCache::GetOrCreateVolumeField(...)` 预热 volume SRV。
|
||||
5. 只要某个必要资源创建失败,就返回 `false`。
|
||||
|
||||
## 当前语义
|
||||
|
||||
- 这是场景相关的资源预热步骤,和 [Initialize](Initialize.md) 的“基础一次性准备”不同。
|
||||
- 当 `visibleVolumes` 为空时,该接口会返回 `true`。
|
||||
- 对不满足绘制条件的体积条目,当前实现会直接跳过,而不是报错。
|
||||
|
||||
## 真实接入位置
|
||||
|
||||
- [BuiltinForwardPipeline](../../Pipelines/BuiltinForwardPipeline/BuiltinForwardPipeline.md) 当前会在场景存在体积时提前调用它,避免真正进入 [Execute](Execute.md) 后才发现 volume 资源还没准备好。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [BuiltinVolumetricPass](BuiltinVolumetricPass.md)
|
||||
- [Initialize](Initialize.md)
|
||||
- [Execute](Execute.md)
|
||||
- [VisibleVolumeItem](../../FrameData/VisibleVolumeItem/VisibleVolumeItem.md)
|
||||
- [RenderResourceCache](../../Caches/RenderResourceCache/RenderResourceCache.md)
|
||||
|
||||
@@ -13,12 +13,17 @@
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `objectIdTextureView` | object-id 纹理视图。 |
|
||||
| `objectIdTextureState` | object-id 纹理在进入 pass 前的资源状态。 |
|
||||
| `objectIdTextureState` | object-id 纹理在进入本 pass 前的资源状态。 |
|
||||
|
||||
## 当前作用
|
||||
|
||||
- 为 `BuiltinObjectIdOutlinePass::Render(...)` 提供 object-id SRV 与恢复状态信息。
|
||||
- 当 surface 开启自动状态切换时,`objectIdTextureState` 会被当作进入 pass 前的原始状态,用于从/恢复到 `PixelShaderResource`。
|
||||
- 为 `BuiltinObjectIdOutlinePass::Render(...)` 提供 object-id 输入 SRV。
|
||||
- 在目标 `surface` 开启自动状态切换时,提供“进入 pass 前”的原始状态,以便 pass 临时切到 `PixelShaderResource` 并在结束后恢复。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 这个结构只描述 object-id 输入,不描述输出 surface。
|
||||
- 当 `surface.IsAutoTransitionEnabled()` 为 `false` 时,pass 不会自动验证这里声明的状态是否与真实资源状态一致。
|
||||
|
||||
## 相关文档
|
||||
|
||||
|
||||
Reference in New Issue
Block a user