2026-03-26 21:32:43 +08:00
|
|
|
|
# Scene Extraction And Builtin Forward Pipeline
|
|
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
## 这条链路现在怎么工作
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
当前 XCEngine 的主场景渲染链路可以按下面的顺序理解:
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
1. `SceneRenderer` 负责组织相机请求和执行顺序。
|
|
|
|
|
|
2. `CameraRenderer` 选择主渲染管线;默认情况下,它通过 `BuiltinForwardPipelineAsset` 创建 `BuiltinForwardPipeline`。
|
|
|
|
|
|
3. `RenderSceneExtractor` 把 scene/game-object/component 结构压平成 `RenderSceneData`。
|
|
|
|
|
|
4. `BuiltinForwardPipeline` 把 `RenderSceneData` 绘制到 `RenderSurface`。
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
这里的关键点不是“有没有前向渲染”,而是场景数据和绘制数据已经被拆成两层:
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
- 提取阶段负责从场景组织里收集相机、光照和可绘制项。
|
|
|
|
|
|
- pipeline 阶段只消费已经整理好的 `RenderSceneData`。
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
不过这里讲的只是主场景绘制槽位,不是整次相机提交的完整尾段。按 `engine/src/Rendering/CameraRenderer.cpp` 的当前实现,`BuiltinForwardPipeline` 前后还可能包着:
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
- `preScenePasses`
|
|
|
|
|
|
- object-id pass
|
|
|
|
|
|
- `postScenePasses`
|
|
|
|
|
|
- `overlayPasses`
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
Scene View 的网格、选中描边和 editor overlay,当前就是先在 Editor 层组装成这些 request 级序列,再交给 `CameraRenderer` 执行。
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
## `RenderSceneData` 现在包含什么
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
`RenderSceneExtractor` 当前产出的核心数据有三块:
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
- `camera` 与 `cameraData`
|
|
|
|
|
|
- `lighting`
|
|
|
|
|
|
- `visibleItems`
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
其中 `visibleItems` 的元素类型是 `VisibleRenderItem`。头文件里仍保留 `VisibleRenderObject = VisibleRenderItem` 的兼容别名,但当前实现和新文档都应以 `visibleItems` 为准,而不是旧说法 `visibleObjects`。
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
每个 `VisibleRenderItem` 除了 mesh 和变换,还已经携带:
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
- `material`
|
|
|
|
|
|
- `materialIndex`
|
|
|
|
|
|
- `sectionIndex`
|
|
|
|
|
|
- `hasSection`
|
|
|
|
|
|
- `renderQueue`
|
|
|
|
|
|
- `cameraDistanceSq`
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
这让后续 pipeline 不需要回到场景层重新做组件查询。
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
## 为什么还要保留 scene extraction
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
游戏对象系统天然偏向层级、组件和编辑器语义;渲染系统天然偏向“当前相机要画哪些项”。`RenderSceneExtractor` 的价值就是把这两种数据形状解耦。
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
当前 extractor 已经做的事情包括:
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
- 选择相机并生成 `RenderCameraData`
|
|
|
|
|
|
- 提取主方向光数据
|
|
|
|
|
|
- 递归收集满足基础绘制条件的可见项
|
|
|
|
|
|
- 产出 `visibleItems` 并带上 material / section / distance 等渲染侧字段
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
它还没有做完整的商业级可见性系统,例如:
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
- 视锥裁剪
|
|
|
|
|
|
- 遮挡裁剪
|
|
|
|
|
|
- instancing / batching
|
|
|
|
|
|
- 透明排序主路径
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
## `BuiltinForwardPipeline` 的当前定位
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
`BuiltinForwardPipeline` 现在是默认主渲染路径,但它内部已经不是旧的固定绑定模型,而是三层缓存:
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
- 按 `(shader*, passName)` 缓存 `PassResourceLayout`
|
|
|
|
|
|
- 按 `(shader*, passName, render state)` 缓存 `RHIPipelineState`
|
|
|
|
|
|
- 按 `(passLayout, setIndex, objectId, material)` 缓存动态 descriptor set
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
此外它已经接入 [RenderPassSequence](../../XCEngine/Rendering/RenderPass/RenderPass.md):
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
- 构造时注册 `BuiltinForwardOpaquePass`
|
|
|
|
|
|
- `Initialize()` 走 sequence 生命周期
|
|
|
|
|
|
- `Render()` 先构造 `RenderPassContext`,再执行 sequence
|
|
|
|
|
|
- `Shutdown()` 也走 sequence,再由 opaque pass 回调资源清理
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
所以当前 builtin forward 更像“一条默认可运行的 pass-sequence 管线”,而不是过去那种把所有逻辑揉在一个固定 layout 里的实现。
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
## Shader pass 资源契约
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
当前 builtin forward 对 shader pass 的资源声明有明确白名单。可识别语义只有:
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
- `PerObject`:必需,单个 CBV
|
|
|
|
|
|
- `Material`:可选,单个 CBV
|
|
|
|
|
|
- `BaseColorTexture`:可选,单个 `Texture2D` 或 `TextureCube`
|
|
|
|
|
|
- `LinearClampSampler`:可选,单个 sampler
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
如果 shader pass 没有声明 `resources`,则会回退到 legacy builtin forward 绑定:
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
- `set 1 binding 0` -> `PerObject`
|
|
|
|
|
|
- `set 2 binding 0` -> `Material`
|
|
|
|
|
|
- `set 3 binding 0` -> `BaseColorTexture`
|
|
|
|
|
|
- `set 4 binding 0` -> `LinearClampSampler`
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
如果声明不合法,例如未知语义、同 set 混用 sampler 和非 sampler、重复 binding 或缺少 `PerObject`,pipeline 会拒绝为该 pass 创建布局。
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
测试 `tests/Rendering/unit/test_builtin_forward_pipeline.cpp` 还明确校验了 builtin shader `ForwardLit` pass 的这组资源契约,以及 `BuildInputLayout()` 现在使用 `POSITION=float3`。
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
## 单个可见项如何被画出来
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
当 `BuiltinForwardOpaquePass` 遍历 `RenderSceneData::visibleItems` 时,每个物体大致会经历以下步骤:
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
1. 根据材质解析真正要用的 shader/pass;没有合适 pass 时回退到 builtin forward shader。
|
|
|
|
|
|
2. 取得 mesh 的 GPU 资源缓存。
|
|
|
|
|
|
3. 生成 `PerObjectConstants` 和 `PerMaterialConstants`。
|
|
|
|
|
|
4. 获取或创建当前 shader pass 的 `PassResourceLayout`。
|
|
|
|
|
|
5. 逐 set 绑定 descriptor:
|
|
|
|
|
|
- 含 `PerObject / Material / Texture` 的 set 走动态缓存。
|
|
|
|
|
|
- 只含 sampler 的 set 走静态缓存。
|
|
|
|
|
|
6. 按 section 或整 mesh 发出 draw call。
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
`BaseColorTexture` 如果解析不到,会回退到初始化阶段创建的 1x1 白色纹理 SRV。
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
## `RenderSurface` 在这里的作用
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
`RenderSurface` 不是单纯的附件容器,而是当前这一帧输出目标的完整描述。builtin forward 会消费它的:
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
- 颜色附件
|
|
|
|
|
|
- 深度附件
|
|
|
|
|
|
- render area
|
|
|
|
|
|
- clear color override
|
|
|
|
|
|
- 自动状态切换开关
|
|
|
|
|
|
- `colorStateBefore` / `colorStateAfter`
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
因此这条主渲染路径既能服务于窗口 back buffer,也能服务于 editor viewport、离屏 RT 或其它自定义输出目标。
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
## 当前限制
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
2026-04-03 15:30:47 +08:00
|
|
|
|
- 主场景默认只有 builtin forward opaque pass。
|
|
|
|
|
|
- 透明、阴影、延迟渲染和更复杂的资源依赖管理还不在这条链路里。
|
|
|
|
|
|
- `RenderPassSequence` 目前只提供顺序执行,不是 render graph。
|
2026-03-26 21:32:43 +08:00
|
|
|
|
|
|
|
|
|
|
## 相关 API
|
|
|
|
|
|
|
|
|
|
|
|
- [Rendering](../../XCEngine/Rendering/Rendering.md)
|
2026-04-10 17:14:27 +08:00
|
|
|
|
- [RenderSceneExtractor](../../XCEngine/Rendering/Extraction/RenderSceneExtractor/RenderSceneExtractor.md)
|
2026-03-26 21:32:43 +08:00
|
|
|
|
- [RenderSurface](../../XCEngine/Rendering/RenderSurface/RenderSurface.md)
|
2026-04-03 15:30:47 +08:00
|
|
|
|
- [RenderPass](../../XCEngine/Rendering/RenderPass/RenderPass.md)
|
2026-04-10 17:14:27 +08:00
|
|
|
|
- [SceneRenderer](../../XCEngine/Rendering/Execution/SceneRenderer/SceneRenderer.md)
|
2026-03-26 21:32:43 +08:00
|
|
|
|
- [BuiltinForwardPipeline](../../XCEngine/Rendering/Pipelines/BuiltinForwardPipeline/BuiltinForwardPipeline.md)
|
2026-04-03 15:30:47 +08:00
|
|
|
|
- [BuiltinForwardPipelineAsset](../../XCEngine/Rendering/Pipelines/BuiltinForwardPipelineAsset/BuiltinForwardPipelineAsset.md)
|
2026-03-26 21:32:43 +08:00
|
|
|
|
- [MeshFilterComponent](../../XCEngine/Components/MeshFilterComponent/MeshFilterComponent.md)
|
|
|
|
|
|
- [MeshRendererComponent](../../XCEngine/Components/MeshRendererComponent/MeshRendererComponent.md)
|