Files
XCEngine/docs/api/XCEngine/Rendering/Execution/CameraRenderer/CameraRenderer.md

108 lines
4.9 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.
# CameraRenderer
**命名空间**: `XCEngine::Rendering`
**类型**: `class`
**头文件**: `XCEngine/Rendering/Execution/CameraRenderer.h`
**描述**: 单个 `CameraRenderRequest` 的执行器,负责把一份显式 request 变成稳定的逐阶段渲染流程。
## 概览
`CameraRenderer` 是 Execution 层里最靠近“真正发起一次相机渲染”的类。
它不负责决定应该渲染哪些相机,也不负责 request 排序;这些职责在 [Planning](../../Planning/Planning.md) 和 [SceneRenderer](../SceneRenderer/SceneRenderer.md)。
它负责的是另一半:把一份已经构造好的 `CameraRenderRequest` 按当前引擎约定的阶段顺序完整跑完。
## 当前持有对象
- `m_sceneExtractor`
负责把 `Scene + Camera` 压成 `RenderSceneData`
- `m_pipelineAsset`
当前主管线的创建来源;为空时表示直接持有 runtime pipeline。
- `m_pipeline`
真正执行主场景绘制的 [RenderPipeline](../../RenderPipeline/RenderPipeline.md)。
- `m_objectIdPass`
object-id 输出阶段使用的 `RenderPass`
- `m_depthOnlyPass`
depth-only 阶段使用的 `RenderPass`
- `m_shadowCasterPass`
shadow-caster 阶段使用的 `RenderPass`
- `m_directionalShadowSurface`
当 request 只提供 `DirectionalShadowRenderPlan`、而没有显式 `shadowCaster.surface` 时,按需生成阴影贴图 surface。
- `m_postProcessSurfaceCache`
- `m_finalOutputSurfaceCache`
fullscreen 阶段多 pass 链使用的中间 surface cache。
## 当前执行顺序
`CameraRenderer::Render(...)` 会按 `kOrderedCameraFrameStages` 依次执行:
1. `PreScenePasses`
2. `ShadowCaster`
3. `DepthOnly`
4. `MainScene`
5. `PostProcess`
6. `FinalOutput`
7. `ObjectId`
8. `PostScenePasses`
9. `OverlayPasses`
其中:
- `MainScene` 永远会尝试执行。
- 其他阶段是否执行,由 `CameraRenderRequest::HasFrameStage(...)` 决定。
- `ShadowCaster` 既可以消费显式 `request.shadowCaster`,也可以由 `request.directionalShadow` 推导出内部阴影 surface。
## 设计要点
### 为什么这里坚持“显式阶段链”
这和 Unity SRP 里常见的 camera render loop 思路相似每个阶段有稳定顺序request 只是声明“这一帧这个阶段要不要做”。
这样做的好处是:
- post-process、final-output 和 editor 注入 pass 都能接到同一条链上
- 不同调用方不需要各自复制一套“主场景之后到底先做什么”的隐式约定
- object-id、selection、scene view overlay 这类非主画面输出,不会反向污染主管线实现
### 为什么 fullscreen 阶段不放到 pipeline 内部
`RenderPipeline` 关注的是主场景绘制fullscreen 链更像是 request 级组合层。
把它们留在 `CameraRenderer`,可以让不同 pipeline 共享一致的 post-process / final-output 接线方式。
## 当前实现边界
- 这里只执行单个 request不负责 request 排序。
- 这里只消费 request 上已经挂好的 sequence / sub-request不负责为 Editor 自动生成这些附加阶段。
- `RenderPassSequence` 的生命周期由 request 拥有方管理;当前实现不会在一次 `Render()` 结束后主动销毁这些 sequence。
## 公开方法
| 方法 | 说明 |
|------|------|
| [Constructor](Constructor.md) | 构造执行器,并决定主管线与 builtin pass 的初始来源。 |
| [Destructor](Destructor.md) | 关闭当前主管线与 builtin pass。 |
| [SetPipeline](SetPipeline.md) | 直接替换 runtime `RenderPipeline`。 |
| [SetPipelineAsset](SetPipelineAsset.md) | 通过 `RenderPipelineAsset` 重建当前主管线。 |
| [SetObjectIdPass](SetObjectIdPass.md) | 替换 object-id pass。 |
| [SetDepthOnlyPass](SetDepthOnlyPass.md) | 替换 depth-only pass。 |
| [SetShadowCasterPass](SetShadowCasterPass.md) | 替换 shadow-caster pass。 |
| [GetPipeline](GetPipeline.md) | 返回当前主管线的非拥有指针。 |
| [GetPipelineAsset](GetPipelineAsset.md) | 返回当前 pipeline asset 的非拥有指针。 |
| [GetObjectIdPass](GetObjectIdPass.md) | 返回当前 object-id pass 的非拥有指针。 |
| [GetDepthOnlyPass](GetDepthOnlyPass.md) | 返回当前 depth-only pass 的非拥有指针。 |
| [GetShadowCasterPass](GetShadowCasterPass.md) | 返回当前 shadow-caster pass 的非拥有指针。 |
| [Render](Render.md) | 执行一次完整的单相机 request。 |
## 相关文档
- [Execution](../Execution.md)
- [SceneRenderer](../SceneRenderer/SceneRenderer.md)
- [CameraRenderRequest](../../Planning/CameraRenderRequest/CameraRenderRequest.md)
- [RenderSceneExtractor](../../Extraction/RenderSceneExtractor/RenderSceneExtractor.md)
- [BuiltinForwardPipeline](../../Pipelines/BuiltinForwardPipeline/BuiltinForwardPipeline.md)
- [BuiltinObjectIdPass](../../Passes/BuiltinObjectIdPass/BuiltinObjectIdPass.md)
- [BuiltinDepthOnlyPass](../../Passes/BuiltinDepthOnlyPass/BuiltinDepthOnlyPass.md)
- [BuiltinShadowCasterPass](../../Passes/BuiltinShadowCasterPass/BuiltinShadowCasterPass.md)