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

108 lines
4.9 KiB
Markdown
Raw Normal View History

# 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)