Files
XCEngine/docs/api/XCEngine/Rendering/Passes/BuiltinObjectIdPass/BuiltinObjectIdPass.md

69 lines
3.8 KiB
Markdown
Raw Normal View History

# BuiltinObjectIdPass
**命名空间**: `XCEngine::Rendering::Passes`
**类型**: `class`
**头文件**: `XCEngine/Rendering/Passes/BuiltinObjectIdPass.h`
**描述**: `ObjectIdPass` 的当前内建实现,把可见物体渲染到 object-id 颜色目标,供拾取和后续选择描边使用。
## 概述
`BuiltinObjectIdPass` 可以理解成主场景渲染旁边的一条辅助输出路径:
- 主颜色目标仍由当前 `RenderPipeline` 负责。
- object-id 目标由这条 pass 用单独 shader 再画一遍可见物体。
- 每个物体的 `GameObject::GetID()` 会被编码成 RGBA 颜色写入目标纹理。
这样后续只要采样这张 object-id 纹理,就能做选中描边、拾取或调试显示,而不必回读主颜色缓冲。
## 当前实现流程
1. 校验 `RenderContext`、颜色附件、深度附件和 `RenderSurface` 的 render area。
2. 惰性创建 pipeline layout、pipeline state 和 builtin object-id shader。
3. 如果 `RenderSurface` 开启自动状态切换,先把颜色附件切到 `RenderTarget`
4. 清空 object-id 颜色目标为全零。
5. 遍历 `RenderSceneData::visibleItems`,按物体 ID 建立或复用常量缓冲并发出 draw call。
6. 若开启自动状态切换,再把颜色附件切回 `surface.GetColorStateAfter()`
## 关键实现细节
- 当前 input layout 沿用 `Resources::StaticMeshVertex``POSITION / NORMAL / TEXCOORD0` 三元素布局,而不是单独定义一套 object-id 专用顶点流。
- 每个 object ID 会缓存一套独立 descriptor set避免重复分配常量绑定。
- `RenderResourceCache` 负责把 `Mesh` 上传或复用成 GPU 资源。
- 资源声明会优先读取 shader pass 自己的 `resources`,若为空则回退到 [BuildLegacyBuiltinObjectIdPassResourceBindings](../../RenderMaterialUtility/BuildLegacyBuiltinObjectIdPassResourceBindings.md),再统一交给 [TryBuildBuiltinPassResourceBindingPlan](../../RenderMaterialUtility/TryBuildBuiltinPassResourceBindingPlan.md) 解析。
- shader pass 解析优先匹配 builtin object-id pass tag其次回退到 `ObjectId` / `EditorObjectId` 命名,最后才退到首个 pass。
## 当前实现边界
- 这条 pass 依赖调用方先准备好 `RenderSceneData`,自己不做 scene extraction。
- 只处理第一个颜色附件和一个深度附件。
- 当前 object-id 绘制仍是逐物体提交,没有更高级的 batching。
- viewport 与 scissor 使用 `surface.GetRenderArea()`,因此 object-id 输出会跟随当前 request 的子视口。
- 是否支持某个后端,取决于 builtin object-id shader 是否提供对应 graphics variant现有 shader loader 测试覆盖了 D3D12、OpenGL 和 Vulkan 三种 builtin variant。
## 公开方法
| 方法 | 说明 |
|------|------|
| [Destructor](Destructor.md) | 析构时关闭内部缓存的 pipeline、descriptor set 和 shader handle。 |
| [BuildInputLayout](BuildInputLayout.md) | 生成 object-id pass 当前使用的顶点布局。 |
| [Render](Render.md) | 把 `visibleItems` 再绘制一遍到 object-id 目标。 |
| [Shutdown](Shutdown.md) | 主动销毁当前缓存的 GPU 资源。 |
## 真实使用位置
- `CameraRenderer::Render()` 在主场景渲染后、`postScenePasses``overlayPasses` 前调用 `m_objectIdPass->Render(...)`
2026-04-04 01:10:38 +08:00
- `tests/Editor/test_viewport_render_flow_utils.cpp` 验证了 scene viewport 会为 `CameraRenderRequest::objectId` 正确挂接颜色/深度附件,并在 render plan 侧单独处理 object-id shader view。
- `tests/Resources/Shader/test_shader_loader.cpp` 验证了 builtin object-id shader 的 pass tag 和多后端 variant 是否存在。
## 相关文档
- [Passes](../Passes.md)
- [BuildInputLayout](BuildInputLayout.md)
- [Render](Render.md)
- [Shutdown](Shutdown.md)
- [BuiltinObjectIdOutlinePass](../BuiltinObjectIdOutlinePass/BuiltinObjectIdOutlinePass.md)
- [CameraRenderer](../../CameraRenderer/CameraRenderer.md)