2026-04-07 00:17:51 +08:00
|
|
|
|
# RenderSceneExtractor
|
|
|
|
|
|
|
|
|
|
|
|
**命名空间**: `XCEngine::Rendering`
|
|
|
|
|
|
|
|
|
|
|
|
**类型**: `class`
|
|
|
|
|
|
|
|
|
|
|
|
**头文件**: `XCEngine/Rendering/Extraction/RenderSceneExtractor.h`
|
|
|
|
|
|
|
2026-04-10 16:55:33 +08:00
|
|
|
|
**描述**: 把场景对象树压平成执行层可直接消费的 `RenderSceneData`,负责相机选择、可见渲染项/体积项提取和光照快照构建。
|
2026-04-07 00:17:51 +08:00
|
|
|
|
|
|
|
|
|
|
## 概览
|
|
|
|
|
|
|
2026-04-10 16:55:33 +08:00
|
|
|
|
`RenderSceneExtractor` 是运行时场景语义和渲染提交语义之间的桥。
|
|
|
|
|
|
它不负责发 draw call,而是把 `Scene` 转换成一份更稳定的帧数据快照,供 [CameraRenderer](../../Execution/CameraRenderer/CameraRenderer.md) 和各类 builtin pass 消费。
|
2026-04-07 00:17:51 +08:00
|
|
|
|
|
2026-04-10 16:55:33 +08:00
|
|
|
|
当前导出的 `RenderSceneData` 重点包含:
|
2026-04-07 00:17:51 +08:00
|
|
|
|
|
2026-04-10 16:55:33 +08:00
|
|
|
|
- `camera`
|
|
|
|
|
|
- `cameraData`
|
|
|
|
|
|
- `environment`
|
|
|
|
|
|
- `lighting`
|
|
|
|
|
|
- `globalShaderKeywords`
|
2026-04-07 00:17:51 +08:00
|
|
|
|
- `visibleItems`
|
2026-04-09 23:40:43 +08:00
|
|
|
|
- `visibleVolumes`
|
2026-04-07 00:17:51 +08:00
|
|
|
|
|
2026-04-10 16:55:33 +08:00
|
|
|
|
## 公开方法
|
|
|
|
|
|
|
|
|
|
|
|
| 方法 | 说明 |
|
|
|
|
|
|
|------|------|
|
|
|
|
|
|
| [Extract](Extract.md) | 自动选择相机并提取 `RenderSceneData`。 |
|
|
|
|
|
|
| [ExtractForCamera](ExtractForCamera.md) | 使用显式相机提取 `RenderSceneData`。 |
|
|
|
|
|
|
| [SelectCamera](SelectCamera.md) | 按当前规则选择可用相机。 |
|
|
|
|
|
|
|
|
|
|
|
|
## 当前提取规则
|
|
|
|
|
|
|
|
|
|
|
|
### 相机选择
|
|
|
|
|
|
|
|
|
|
|
|
- `overrideCamera` 可用时优先使用它。
|
|
|
|
|
|
- 否则优先选择场景里深度最高的 `primary` 相机。
|
|
|
|
|
|
- 若没有 primary,相机列表里第一个可用相机会作为回退。
|
|
|
|
|
|
|
|
|
|
|
|
### 可见内容
|
|
|
|
|
|
|
|
|
|
|
|
提取器会从场景根对象开始递归遍历:
|
|
|
|
|
|
|
|
|
|
|
|
- 先按 `IsActiveInHierarchy()` 和相机 `cullingMask` 过滤对象
|
|
|
|
|
|
- 再调用 `RenderSceneUtility` 展开 mesh 渲染项
|
|
|
|
|
|
- 同时调用 `AppendVisibleVolumesForGameObject(...)` 提取体积渲染项
|
|
|
|
|
|
|
|
|
|
|
|
因此当前 `RenderSceneData` 已经同时覆盖:
|
|
|
|
|
|
|
|
|
|
|
|
- 常规 mesh 的 `visibleItems`
|
|
|
|
|
|
- 体积渲染的 `visibleVolumes`
|
|
|
|
|
|
|
|
|
|
|
|
两类结果都会在提取结束后做稳定排序。
|
|
|
|
|
|
|
|
|
|
|
|
### 光照快照
|
|
|
|
|
|
|
|
|
|
|
|
`ExtractLighting(...)` 当前会:
|
|
|
|
|
|
|
|
|
|
|
|
- 选出主方向光并构建 `mainDirectionalLight`
|
|
|
|
|
|
- 基于影响度、光源类型和对象 ID 选出有限数量的 `additionalLights`
|
|
|
|
|
|
- 保留阴影相关槽位,供后续执行层写入 `mainDirectionalShadow`
|
|
|
|
|
|
|
|
|
|
|
|
这意味着 extractor 不只是“找一盏太阳光”,而是已经承担了运行时可消费的光照快照整理职责。
|
|
|
|
|
|
|
|
|
|
|
|
## 设计取舍
|
|
|
|
|
|
|
|
|
|
|
|
这类 extractor 设计和 Unity/Unreal 常见的 render-view 构建阶段类似,本质上是在做一件事:
|
|
|
|
|
|
把场景图的层级语义压扁成一份更适合渲染排序、pass 复用和后续 GPU 提交的帧快照。
|
|
|
|
|
|
|
|
|
|
|
|
这样做的好处很直接:
|
|
|
|
|
|
|
|
|
|
|
|
- `CameraRenderer` 不必在执行阶段重新遍历整个场景树
|
|
|
|
|
|
- builtin pipeline、object-id pass、体积 pass 可以共享同一批 frame data
|
|
|
|
|
|
- editor 或工具链要加附加阶段时,不必重新发明一套“场景如何提取”的规则
|
|
|
|
|
|
|
2026-04-07 00:17:51 +08:00
|
|
|
|
## 当前实现边界
|
|
|
|
|
|
|
2026-04-10 16:55:33 +08:00
|
|
|
|
- 没有 frustum culling。
|
|
|
|
|
|
- 没有 occlusion culling。
|
|
|
|
|
|
- 没有 batching / instancing。
|
|
|
|
|
|
- `globalShaderKeywords` 主要仍由后续执行层补充。
|
2026-04-07 00:17:51 +08:00
|
|
|
|
|
|
|
|
|
|
## 相关文档
|
|
|
|
|
|
|
|
|
|
|
|
- [Extraction](../Extraction.md)
|
|
|
|
|
|
- [RenderSceneUtility](../RenderSceneUtility/RenderSceneUtility.md)
|
|
|
|
|
|
- [RenderSceneData](../../FrameData/RenderSceneData/RenderSceneData.md)
|
2026-04-10 16:55:33 +08:00
|
|
|
|
- [VisibleRenderItem](../../FrameData/VisibleRenderItem/VisibleRenderItem.md)
|
|
|
|
|
|
- [VisibleVolumeItem](../../FrameData/VisibleVolumeItem/VisibleVolumeItem.md)
|
2026-04-07 00:17:51 +08:00
|
|
|
|
- [CameraRenderer](../../Execution/CameraRenderer/CameraRenderer.md)
|