Files
XCEngine/docs/api/_guides/Rendering/Scene-Extraction-And-Builtin-Forward-Pipeline.md

147 lines
6.4 KiB
Markdown
Raw Blame History

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