Restore unrelated rendering docs

This commit is contained in:
2026-04-10 00:42:53 +08:00
parent 02a0e626fe
commit 34a32b73dd
23 changed files with 1092 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
# CameraRenderer
**命名空间**: `XCEngine::Rendering`
**类型**: `class`
**头文件**: `XCEngine/Rendering/Execution/CameraRenderer.h`
**描述**: 单个 `CameraRenderRequest` 的执行器,负责在一次提交里串起 scene extraction、shadow/depth 预 pass、主主管线、object-id以及注入式 pre/post/overlay pass。
## 概述
`CameraRenderer` 是当前 Rendering 模块里的“单 request 执行层”。它不负责决定应该渲染哪些相机,也不负责 request 排序;这些职责在 [SceneRenderer](../SceneRenderer/SceneRenderer.md) 与 [SceneRenderRequestPlanner](../SceneRenderRequestPlanner/SceneRenderRequestPlanner.md)。
它关心的是另一件事:一份已经组装好的 `CameraRenderRequest`,到底按什么顺序跑完。
## 当前持有的运行时对象
- `m_sceneExtractor`
使用 request surface 的 render-area 尺寸提取当前相机对应的 `RenderSceneData`
- `m_pipelineAsset`
当前主管线的创建来源工厂;可能为空。
- `m_pipeline`
当前实际执行主场景绘制的 runtime [RenderPipeline](../RenderPipeline/RenderPipeline.md)。
- `m_objectIdPass`
按需消费 `request.objectId` 的 object-id pass默认是 [Passes::BuiltinObjectIdPass](../Passes/BuiltinObjectIdPass/BuiltinObjectIdPass.md)。
- `m_depthOnlyPass`
按需消费 `request.depthOnly` 的独立 scene pass默认是 [Passes::BuiltinDepthOnlyPass](../Passes/BuiltinDepthOnlyPass/BuiltinDepthOnlyPass.md)。
- `m_shadowCasterPass`
按需消费 `request.shadowCaster` 的独立 scene pass默认是 [Passes::BuiltinShadowCasterPass](../Passes/BuiltinShadowCasterPass/BuiltinShadowCasterPass.md)。
这意味着 `CameraRenderer` 不替调用方生成 Scene View 的特殊效果,但会直接消费 request 上已经明确给出的 depth-only / shadow-caster / object-id / post / overlay 槽位。
## 当前执行顺序
对一份有效 request当前 `Render()` 的主顺序是:
1. 校验 request、自身主管线、render-area以及 `shadowCaster / depthOnly / objectId` 请求前置条件。
2.`m_sceneExtractor.ExtractForCamera(...)` 生成 `RenderSceneData`
3. 用 request 覆盖 `sceneData.cameraData.clearFlags`,必要时再覆盖 `clearColor`
4. 执行 `preScenePasses`
5. 如请求了 shadow-caster执行 `m_shadowCasterPass`
6. 如请求了 depth-only执行 `m_depthOnlyPass`
7. 执行 `m_pipeline->Render(...)`
8. 如请求了 object-id执行 `m_objectIdPass->Render(...)`
9. 执行 `postScenePasses`
10. 执行 `overlayPasses`
11. 按已初始化的 sequence 逆向 `Shutdown()`
`tests/Rendering/unit/test_camera_scene_renderer.cpp` 已覆盖这条顺序,包括 shadow-caster / depth-only 位于主主管线之前这一点。
## 生命周期与回退策略
- 默认构造会使用静态共享的 [BuiltinForwardPipelineAsset](../Pipelines/BuiltinForwardPipelineAsset/BuiltinForwardPipelineAsset.md),并同时创建 builtin object-id / depth-only / shadow-caster pass。
- `SetPipeline()` 走“手动注入 runtime pipeline”路径并清空当前 `m_pipelineAsset`
- `SetPipelineAsset()` 走“由 asset 创建 runtime pipeline”路径传空时会回退到默认 asset。
- `ResetPipeline()` 会先 `Shutdown()` 旧主管线,再接管新实例;若新实例为空,则再次回退到默认 asset 并创建 builtin forward。
- [SetObjectIdPass](SetObjectIdPass.md) 会先关闭旧 pass传空时回退到 builtin object-id pass。
- [SetDepthOnlyPass](SetDepthOnlyPass.md) 会先关闭旧 pass传空时回退到 builtin depth-only pass。
- [SetShadowCasterPass](SetShadowCasterPass.md) 会先关闭旧 pass传空时回退到 builtin shadow-caster pass。
## 当前验证规则
`Render()` 当前会显式拒绝:
- `request.IsValid()` 为假
- 当前 `m_pipeline == nullptr`
- `request.surface` 的 render-area 宽或高为 `0`
- 请求了 shadow-caster`request.shadowCaster.IsValid()` 为假
- 请求了 depth-only`request.depthOnly.IsValid()` 为假
- 请求了 object-id`request.objectId.IsValid()` 为假
## 当前实现边界
- 这里只执行单个 request多相机排序、stack 顺序和 clear 规则在 `SceneRenderer` / `SceneRenderRequestPlanner` 层完成。
- 这里只消费 request 上已经存在的 scene-pass 与 pass-sequence 槽位,不主动构建 editor 专用 overlay。
- post / overlay 阶段仍然只是顺序执行的 `RenderPassSequence`,不是 render graph。
## 公开方法
| 方法 | 说明 |
|------|------|
| [Constructor](Constructor.md) | 构造 `CameraRenderer`,并决定主主管线与 builtin 独立 pass 的初始来源。 |
| [Destructor](Destructor.md) | 关闭当前主管线、object-id pass、depth-only pass 与 shadow-caster pass。 |
| [SetPipeline](SetPipeline.md) | 手动替换当前 runtime pipeline。 |
| [SetPipelineAsset](SetPipelineAsset.md) | 通过 `RenderPipelineAsset` 重建当前 runtime pipeline。 |
| [SetObjectIdPass](SetObjectIdPass.md) | 替换当前 object-id pass。 |
| [SetDepthOnlyPass](SetDepthOnlyPass.md) | 替换当前 depth-only scene pass。 |
| [SetShadowCasterPass](SetShadowCasterPass.md) | 替换当前 shadow-caster scene 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) | 执行一次完整的单相机提交。 |
## 相关文档
- [Rendering](../Rendering.md)
- [SceneRenderer](../SceneRenderer/SceneRenderer.md)
- [CameraRenderRequest](../CameraRenderRequest/CameraRenderRequest.md)
- [RenderSceneExtractor](../RenderSceneExtractor/RenderSceneExtractor.md)
- [RenderPipeline](../RenderPipeline/RenderPipeline.md)
- [ObjectIdPass](../ObjectIdPass/ObjectIdPass.md)
- [BuiltinDepthOnlyPass](../Passes/BuiltinDepthOnlyPass/BuiltinDepthOnlyPass.md)
- [BuiltinShadowCasterPass](../Passes/BuiltinShadowCasterPass/BuiltinShadowCasterPass.md)
- [Camera Request Planning And Clear Rules](../../../_guides/Rendering/Camera-Request-Planning-And-Clear-Rules.md)
- [Scene Extraction And Builtin Forward Pipeline](../../../_guides/Rendering/Scene-Extraction-And-Builtin-Forward-Pipeline.md)

View File

@@ -0,0 +1,73 @@
# CameraRenderer::Constructor
**命名空间**: `XCEngine::Rendering`
**类型**: `constructor-overload group`
**头文件**: `XCEngine/Rendering/Execution/CameraRenderer.h`
## 签名
```cpp
CameraRenderer();
explicit CameraRenderer(std::unique_ptr<RenderPipeline> pipeline);
explicit CameraRenderer(std::shared_ptr<const RenderPipelineAsset> pipelineAsset);
CameraRenderer(
std::unique_ptr<RenderPipeline> pipeline,
std::unique_ptr<ObjectIdPass> objectIdPass,
std::unique_ptr<RenderPass> depthOnlyPass = nullptr,
std::unique_ptr<RenderPass> shadowCasterPass = nullptr);
```
## 行为说明
构造函数的核心职责是决定三件事:
- 当前主管线实例从哪里来
- 当前 object-id pass 是否使用默认 builtin 实现
- 当前 depth-only / shadow-caster pass 是否使用默认 builtin 实现
## 当前构造路径
### 默认构造
- 通过内部静态 `CreateDefaultPipelineAsset()` 取得共享的默认 asset。
- 默认 asset 是 [BuiltinForwardPipelineAsset](../Pipelines/BuiltinForwardPipelineAsset/BuiltinForwardPipelineAsset.md)。
- 随后走 asset 构造路径生成 runtime pipeline。
### `std::unique_ptr<RenderPipeline>` 重载
- 交由四参重载处理。
- 如果未显式提供 object-id / depth-only / shadow-caster pass会分别补
- [Passes::BuiltinObjectIdPass](../Passes/BuiltinObjectIdPass/BuiltinObjectIdPass.md)
- [Passes::BuiltinDepthOnlyPass](../Passes/BuiltinDepthOnlyPass/BuiltinDepthOnlyPass.md)
- [Passes::BuiltinShadowCasterPass](../Passes/BuiltinShadowCasterPass/BuiltinShadowCasterPass.md)
### `std::shared_ptr<const RenderPipelineAsset>` 重载
- 先保存 asset。
- 再调用 [SetPipelineAsset](SetPipelineAsset.md),立即由 asset 创建 runtime pipeline。
- 默认同时创建 builtin object-id / depth-only / shadow-caster pass。
### 四参重载
-`objectIdPass` 为空,自动回退到 builtin object-id pass。
-`depthOnlyPass` 为空,自动回退到 builtin depth-only pass。
-`shadowCasterPass` 为空,自动回退到 builtin shadow-caster pass。
- 调用内部 `ResetPipeline(std::move(pipeline))`
- 如果传入 `pipeline` 为空,`ResetPipeline()` 会继续回退到默认 pipeline asset并创建 builtin forward 主管线。
## 所有权
- `RenderPipeline``ObjectIdPass``depthOnlyPass``shadowCasterPass` 都由 `CameraRenderer``std::unique_ptr` 独占持有。
- `RenderPipelineAsset``std::shared_ptr<const ...>` 共享持有,只作为 runtime pipeline 的创建来源。
## 相关文档
- [CameraRenderer](CameraRenderer.md)
- [SetPipeline](SetPipeline.md)
- [SetPipelineAsset](SetPipelineAsset.md)
- [SetObjectIdPass](SetObjectIdPass.md)
- [SetDepthOnlyPass](SetDepthOnlyPass.md)
- [SetShadowCasterPass](SetShadowCasterPass.md)

View File

@@ -0,0 +1,47 @@
# CameraRenderer::~CameraRenderer
**命名空间**: `XCEngine::Rendering`
**类型**: `destructor`
**头文件**: `XCEngine/Rendering/Execution/CameraRenderer.h`
## 签名
```cpp
~CameraRenderer();
```
## 作用
在对象销毁前关闭当前持有的主管线、object-id pass、depth-only pass 和 shadow-caster pass。
## 当前实现行为
析构函数当前按以下顺序执行清理:
1. 如果 `m_pipeline` 非空,调用 `m_pipeline->Shutdown()`
2. 如果 `m_objectIdPass` 非空,调用 `m_objectIdPass->Shutdown()`
3. 如果 `m_depthOnlyPass` 非空,调用 `m_depthOnlyPass->Shutdown()`
4. 如果 `m_shadowCasterPass` 非空,调用 `m_shadowCasterPass->Shutdown()`
随后由 `unique_ptr` 和成员对象自身析构负责释放内存。
## 设计含义
- 主管线、object-id pass、depth-only pass 和 shadow-caster pass 的 GPU 资源回收路径都是显式 `Shutdown()`,而不是只依赖 C++ 析构。
- 调用方注入到 `CameraRenderRequest` 里的 `RenderPassSequence` 并不由这里持有,因此也不在这里做统一回收。
## 注意事项
- 当前没有内部同步;不应在其它线程仍可能访问这些对象时销毁 `CameraRenderer`
- 如果你只是想切换主管线或这些独立 pass不要等到析构应该优先使用 [SetPipeline](SetPipeline.md)、[SetPipelineAsset](SetPipelineAsset.md)、[SetObjectIdPass](SetObjectIdPass.md)、[SetDepthOnlyPass](SetDepthOnlyPass.md) 或 [SetShadowCasterPass](SetShadowCasterPass.md)。
## 相关文档
- [CameraRenderer](CameraRenderer.md)
- [SetPipeline](SetPipeline.md)
- [SetObjectIdPass](SetObjectIdPass.md)
- [SetDepthOnlyPass](SetDepthOnlyPass.md)
- [SetShadowCasterPass](SetShadowCasterPass.md)

View File

@@ -0,0 +1,33 @@
# CameraRenderer::GetDepthOnlyPass
**命名空间**: `XCEngine::Rendering`
**类型**: `method`
**头文件**: `XCEngine/Rendering/Execution/CameraRenderer.h`
## 签名
```cpp
RenderPass* GetDepthOnlyPass() const;
```
## 作用
返回当前 depth-only scene pass 的裸指针。
## 当前实现行为
- 这是头文件内联访问器,直接返回 `m_depthOnlyPass.get()`
- 不转移所有权。
## 注意事项
- 调用 [SetDepthOnlyPass](SetDepthOnlyPass.md) 之后,之前读取到的裸指针可能立刻失效。
- 当前默认返回的通常是 builtin depth-only pass但调用方不应把这个 API 当成“只会返回某个具体类型”的承诺。
## 相关文档
- [SetDepthOnlyPass](SetDepthOnlyPass.md)
- [Render](Render.md)

View File

@@ -0,0 +1,32 @@
# CameraRenderer::GetObjectIdPass
**命名空间**: `XCEngine::Rendering`
**类型**: `method`
**头文件**: `XCEngine/Rendering/Execution/CameraRenderer.h`
## 签名
```cpp
ObjectIdPass* GetObjectIdPass() const;
```
## 作用
返回当前 object-id pass 的裸指针。
## 当前实现行为
- 这是头文件内联访问器,直接返回 `m_objectIdPass.get()`
- 不转移所有权。
## 注意事项
- 调用 [SetObjectIdPass](SetObjectIdPass.md) 后,之前读取到的裸指针可能立即失效。
## 相关文档
- [SetObjectIdPass](SetObjectIdPass.md)
- [Render](Render.md)

View File

@@ -0,0 +1,38 @@
# CameraRenderer::GetPipeline
**命名空间**: `XCEngine::Rendering`
**类型**: `method`
**头文件**: `XCEngine/Rendering/Execution/CameraRenderer.h`
## 签名
```cpp
RenderPipeline* GetPipeline() const;
```
## 作用
返回当前主管线实例的裸指针。
## 当前实现行为
- 这是头文件内联访问器,直接返回 `m_pipeline.get()`
- 不转移所有权,也不提供额外生命周期保证。
## 返回值
- 正常路径下通常会返回一个有效指针,因为构造和 `SetPipeline()` / `SetPipelineAsset()` 都会回退到默认管线。
- 理论上如果对象正处于构造中的异常路径或未来实现改变,也不能把“永不为空”当成稳定契约。
## 注意事项
- 不要长期缓存这个裸指针;调用 [SetPipeline](SetPipeline.md) 或 [SetPipelineAsset](SetPipelineAsset.md) 后它可能立即失效。
## 相关文档
- [SetPipeline](SetPipeline.md)
- [SetPipelineAsset](SetPipelineAsset.md)
- [GetPipelineAsset](GetPipelineAsset.md)

View File

@@ -0,0 +1,33 @@
# CameraRenderer::GetPipelineAsset
**命名空间**: `XCEngine::Rendering`
**类型**: `method`
**头文件**: `XCEngine/Rendering/Execution/CameraRenderer.h`
## 签名
```cpp
const RenderPipelineAsset* GetPipelineAsset() const;
```
## 作用
返回当前绑定的 pipeline asset 裸指针。
## 当前实现行为
- 这是头文件内联访问器,直接返回 `m_pipelineAsset.get()`
- 如果最近一次切换是通过 [SetPipeline](SetPipeline.md) 手动注入实例完成的,这里可能返回 `nullptr`
## 返回值
- 返回当前 asset 裸指针,或空指针。
## 相关文档
- [SetPipelineAsset](SetPipelineAsset.md)
- [SetPipeline](SetPipeline.md)
- [GetPipeline](GetPipeline.md)

View File

@@ -0,0 +1,33 @@
# CameraRenderer::GetShadowCasterPass
**命名空间**: `XCEngine::Rendering`
**类型**: `method`
**头文件**: `XCEngine/Rendering/Execution/CameraRenderer.h`
## 签名
```cpp
RenderPass* GetShadowCasterPass() const;
```
## 作用
返回当前 shadow-caster scene pass 的裸指针。
## 当前实现行为
- 这是头文件内联访问器,直接返回 `m_shadowCasterPass.get()`
- 不转移所有权。
## 注意事项
- 调用 [SetShadowCasterPass](SetShadowCasterPass.md) 之后,之前读取到的裸指针可能立刻失效。
- 当前默认返回的通常是 builtin shadow-caster pass但调用方不应假定返回值一定来自某个具体实现类。
## 相关文档
- [SetShadowCasterPass](SetShadowCasterPass.md)
- [Render](Render.md)

View File

@@ -0,0 +1,83 @@
# CameraRenderer::Render
**命名空间**: `XCEngine::Rendering`
**类型**: `method`
**头文件**: `XCEngine/Rendering/Execution/CameraRenderer.h`
## 签名
```cpp
bool Render(const CameraRenderRequest& request);
```
## 行为说明
执行一次完整的单相机提交。当前实现会把 shadow-caster、depth-only、主场景、object-id以及调用方注入的 pre / post / overlay pass 串成一条固定顺序的执行链。
## 当前流程
1. 校验 `request.IsValid()`,并确认 `m_pipeline` 非空。
2. 拒绝 render-area 宽或高为 `0``surface`
3. 如果请求了 shadow-caster要让 `request.shadowCaster.IsValid()` 为真。
4. 如果请求了 depth-only要让 `request.depthOnly.IsValid()` 为真。
5. 如果请求了 object-id要让 `request.objectId.IsValid()` 为真。
6.`request.surface.GetRenderAreaWidth()` / `GetRenderAreaHeight()` 调用 `m_sceneExtractor.ExtractForCamera(...)`
7.`sceneData.HasCamera()` 为假,则返回 `false`
8. 用 request 覆盖 `sceneData.cameraData.clearFlags`;如果 request 提供了 clear-color override则继续覆盖 `sceneData.cameraData.clearColor`
9. 依次初始化并执行:
- `preScenePasses`
- `m_shadowCasterPass->Execute(...)`
- `m_depthOnlyPass->Execute(...)`
- `m_pipeline->Render(...)`
- `m_objectIdPass->Render(...)`
- `postScenePasses`
- `overlayPasses`
10. 按已经成功初始化的 sequence 做逆向 `Shutdown()`
## `postScenePasses` / `overlayPasses` 接入点
`CameraRenderer` 只消费调用方传入的 pass 序列,不额外构建内部后处理层。
- `postScenePasses` 直接来自调用方提供的 `RenderPassSequence`
- `overlayPasses` 也是同样的注入点
- 编辑器 Scene View 当前会先通过 [SceneViewportRenderPlan](../../Editor/Viewport/SceneViewportRenderPlan/SceneViewportRenderPlan.md) 组装这些序列,再调用 `ApplySceneViewportRenderPlan(...)` 挂到 request
这意味着 Scene View 的无限网格、选中轮廓和编辑器 overlay已经被上移到 request 组装层,不再由 `CameraRenderer` 内部再做一次翻译。与之相对,`shadowCaster``depthOnly` 当前仍属于 `CameraRenderRequest` 上的专用 scene-pass 槽位,由 `CameraRenderer` 直接在主主管线之前消费。
## 失败与清理语义
- 任一验证失败会直接返回 `false`
- `shadowCaster``depthOnly` 请求校验失败时,不会进入主主管线。
- 任一 sequence 初始化失败会立刻执行对应 `Shutdown()` 回滚。
- `shadowCaster``depthOnly`、主管线、object-id pass、post 或 overlay 任一阶段失败,都会按已经初始化过的 sequence 做清理再返回 `false`
## 参数
- `request` - 本次单相机渲染的完整输入。
## 返回值
- 整条提交流成功执行时返回 `true`
- request 校验失败、场景提取失败、主管线失败,或任一附加阶段失败时返回 `false`
## 测试覆盖
`tests/Rendering/unit/test_camera_scene_renderer.cpp` 当前验证了:
- render-area 会影响提取到的相机 viewport 尺寸
- clear-flags 和 clear-color override 会写回 `sceneData.cameraData`
- `shadowCaster / depthOnly / pipeline / object-id / post / overlay` 的执行顺序
- shadow-caster 请求无效、object-id 失败和 post-pass 初始化失败时的回滚路径
## 相关文档
- [CameraRenderer](CameraRenderer.md)
- [CameraRenderRequest](../CameraRenderRequest/CameraRenderRequest.md)
- [RenderSceneExtractor](../RenderSceneExtractor/RenderSceneExtractor.md)
- [RenderPipeline::Render](../RenderPipeline/Render.md)
- [SetDepthOnlyPass](SetDepthOnlyPass.md)
- [SetShadowCasterPass](SetShadowCasterPass.md)
- [Passes](../Passes/Passes.md)

View File

@@ -0,0 +1,36 @@
# CameraRenderer::SetDepthOnlyPass
**命名空间**: `XCEngine::Rendering`
**类型**: `method`
**头文件**: `XCEngine/Rendering/Execution/CameraRenderer.h`
## 签名
```cpp
void SetDepthOnlyPass(std::unique_ptr<RenderPass> depthOnlyPass);
```
## 作用
替换当前用于消费 `request.depthOnly` 的独立 scene pass。
## 当前实现行为
1. 如果旧 `m_depthOnlyPass` 非空,先调用它的 `Shutdown()`
2. 接管新的 `depthOnlyPass`
3. 如果新指针为空,则自动回退到 [Passes::BuiltinDepthOnlyPass](../Passes/BuiltinDepthOnlyPass/BuiltinDepthOnlyPass.md)。
## 关键语义
- 这里替换的是一个普通 `RenderPass`,并不要求具体类型必须来自 builtin pass 层。
- `CameraRenderer::Render()` 只在 `request.depthOnly.IsRequested()` 时才会真正执行这里持有的 pass。
- `tests/Rendering/unit/test_camera_scene_renderer.cpp` 通过 mock pass 验证了这条注入链会在主主管线之前执行,并正确消费 `ScenePassRenderRequest` 的 surface / clear-color override。
## 相关文档
- [GetDepthOnlyPass](GetDepthOnlyPass.md)
- [Render](Render.md)
- [BuiltinDepthOnlyPass](../Passes/BuiltinDepthOnlyPass/BuiltinDepthOnlyPass.md)

View File

@@ -0,0 +1,35 @@
# CameraRenderer::SetObjectIdPass
**命名空间**: `XCEngine::Rendering`
**类型**: `method`
**头文件**: `XCEngine/Rendering/Execution/CameraRenderer.h`
## 签名
```cpp
void SetObjectIdPass(std::unique_ptr<ObjectIdPass> objectIdPass);
```
## 作用
替换主场景之后使用的 object-id 输出 pass。
## 当前实现行为
1. 如果旧 `m_objectIdPass` 非空,先调用它的 `Shutdown()`
2. 接管新的 `objectIdPass`
3. 如果新指针为空,则自动回退到 `Passes::BuiltinObjectIdPass`
## 关键语义
- 这是 object-id 渲染链路的主要注入点,测试里可以通过它替换 mock pass。
- `CameraRenderer::Render()` 只在 `request.objectId.IsRequested()` 时才会真正调用这里持有的 pass。
## 相关文档
- [GetObjectIdPass](GetObjectIdPass.md)
- [Render](Render.md)
- [Passes](../Passes/Passes.md)

View File

@@ -0,0 +1,44 @@
# CameraRenderer::SetPipeline
**命名空间**: `XCEngine::Rendering`
**类型**: `method`
**头文件**: `XCEngine/Rendering/Execution/CameraRenderer.h`
## 签名
```cpp
void SetPipeline(std::unique_ptr<RenderPipeline> pipeline);
```
## 作用
手动替换当前主管线实例,并切断与 `RenderPipelineAsset` 的绑定关系。
## 当前实现行为
1. 先把 `m_pipelineAsset.reset()`,表示后续不再认为当前管线来自某个 asset。
2. 调用内部 `ResetPipeline(std::move(pipeline))`
3. `ResetPipeline()` 会:
- 对旧 `m_pipeline` 调用 `Shutdown()`
- 接管新的 `pipeline`
- 如果新指针为空,则回退到默认 pipeline asset 创建的内建前向管线
## 参数
| 参数 | 说明 |
|------|------|
| `pipeline` | 新的主管线实例所有权。可以为空;为空时会自动回退到默认内建前向管线。 |
## 关键语义
- 这是“直接注入实例”的入口,不会保留原来的 pipeline asset。
- 替换时走的是显式关停旧管线的路径,而不是简单换指针。
## 相关文档
- [SetPipelineAsset](SetPipelineAsset.md)
- [GetPipeline](GetPipeline.md)
- [GetPipelineAsset](GetPipelineAsset.md)

View File

@@ -0,0 +1,36 @@
# CameraRenderer::SetPipelineAsset
**命名空间**: `XCEngine::Rendering`
**类型**: `method`
**头文件**: `XCEngine/Rendering/Execution/CameraRenderer.h`
## 签名
```cpp
void SetPipelineAsset(std::shared_ptr<const RenderPipelineAsset> pipelineAsset);
```
## 作用
通过一份 `RenderPipelineAsset` 重建当前主管线实例。
## 当前实现行为
1. 如果传入的 `pipelineAsset` 非空,则保存它。
2. 如果传入为空,则回退到内部静态默认 asset。
3. 调用 `CreatePipelineFromAsset(m_pipelineAsset)` 创建新的管线实例。
4. 再通过 `ResetPipeline(...)` 关停旧管线并接管新实例。
## 关键语义
- 这是“从 asset 创建实例”的入口,和 [SetPipeline](SetPipeline.md) 的手动注入路径不同。
- 即使 asset 无法返回有效实例,`CreatePipelineFromAsset()` 也会继续回退到内建前向管线。
## 相关文档
- [SetPipeline](SetPipeline.md)
- [GetPipelineAsset](GetPipelineAsset.md)
- [Constructor](Constructor.md)

View File

@@ -0,0 +1,36 @@
# CameraRenderer::SetShadowCasterPass
**命名空间**: `XCEngine::Rendering`
**类型**: `method`
**头文件**: `XCEngine/Rendering/Execution/CameraRenderer.h`
## 签名
```cpp
void SetShadowCasterPass(std::unique_ptr<RenderPass> shadowCasterPass);
```
## 作用
替换当前用于消费 `request.shadowCaster` 的独立 scene pass。
## 当前实现行为
1. 如果旧 `m_shadowCasterPass` 非空,先调用它的 `Shutdown()`
2. 接管新的 `shadowCasterPass`
3. 如果新指针为空,则自动回退到 [Passes::BuiltinShadowCasterPass](../Passes/BuiltinShadowCasterPass/BuiltinShadowCasterPass.md)。
## 关键语义
- 这里替换的是一个普通 `RenderPass`,并不要求必须是 builtin shadow-caster 实现。
- `CameraRenderer::Render()` 只在 `request.shadowCaster.IsRequested()` 时才会执行这里持有的 pass。
- 当前执行顺序里shadow-caster pass 位于 depth-only 与主主管线之前。
## 相关文档
- [GetShadowCasterPass](GetShadowCasterPass.md)
- [Render](Render.md)
- [BuiltinShadowCasterPass](../Passes/BuiltinShadowCasterPass/BuiltinShadowCasterPass.md)

View File

@@ -0,0 +1,45 @@
# SceneRenderer::BuildRenderRequests
```cpp
std::vector<CameraRenderRequest> BuildRenderRequests(
const Components::Scene& scene,
Components::CameraComponent* overrideCamera,
const RenderContext& context,
const RenderSurface& surface) const;
```
## 行为说明
当前实现直接委托给内部 `SceneRenderRequestPlanner`
```cpp
return m_requestPlanner.BuildRequests(scene, overrideCamera, context, surface);
```
## 当前用途
这个方法只负责“规划请求”,不负责真正渲染。生成的每个 `CameraRenderRequest` 会携带:
- 选中的相机
- 相机深度和 stack 顺序
- 针对该相机解析后的 clear-flags
- 继承并裁剪后的 `RenderSurface`
- 随后交给 `CameraRenderer` 执行所需的上下文
## 参数
- `scene` - 要规划的场景。
- `overrideCamera` - 可选的 override 相机;可用时只为它构建请求。
- `context` - 当前渲染上下文。
- `surface` - 当前输出目标模板planner 会基于它推导每个相机的 render-area 和 clear 行为。
## 返回值
-`SceneRenderRequestPlanner` 规则生成的请求数组。
## 相关文档
- [SceneRenderer](SceneRenderer.md)
- [Render](Render.md)
- [SceneRenderRequestPlanner](../SceneRenderRequestPlanner/SceneRenderRequestPlanner.md)
- [CameraRenderRequest](../CameraRenderRequest/CameraRenderRequest.md)

View File

@@ -0,0 +1,33 @@
# SceneRenderer::SceneRenderer
构造一个场景级渲染器。
```cpp
SceneRenderer();
explicit SceneRenderer(std::unique_ptr<RenderPipeline> pipeline);
explicit SceneRenderer(std::shared_ptr<const RenderPipelineAsset> pipelineAsset);
```
## 当前语义
- 三个构造路径的差别只在于内部 `m_cameraRenderer` 如何初始化。
- 默认构造:使用 `CameraRenderer` 的默认构造路径,最终回退到默认 builtin forward pipeline asset。
- `std::unique_ptr<RenderPipeline>` 构造:把调用方提供的 runtime pipeline 直接交给内部 `CameraRenderer` 持有。
- `std::shared_ptr<const RenderPipelineAsset>` 构造:让内部 `CameraRenderer` 通过 asset 创建 runtime pipeline。
## 当前实现细节
- `SceneRenderer` 自己不在构造阶段创建额外的 GPU 资源;真正的 runtime pipeline 创建和回退逻辑都委托给 `CameraRenderer`
- 如果传入的 `pipeline` 是空指针,`CameraRenderer` 会回退到默认 pipeline asset而不是保留一个永久空 pipeline。
- 如果传入的 `pipelineAsset` 是空指针,也会回退到默认 builtin forward asset。
## 测试覆盖
- `tests/Rendering/unit/test_camera_scene_renderer.cpp` 验证了默认构造的 `SceneRenderer` 能创建默认 pipeline 并完成渲染。
- 同一测试文件也覆盖了注入 runtime pipeline 和注入 pipeline asset 两条构造路径。
## 相关文档
- [SceneRenderer](SceneRenderer.md)
- [SetPipeline](SetPipeline.md)
- [SetPipelineAsset](SetPipelineAsset.md)

View File

@@ -0,0 +1,30 @@
# SceneRenderer::~SceneRenderer
销毁场景级渲染器对象。
```cpp
~SceneRenderer() = default;
```
## 当前语义
- `SceneRenderer` 自身没有自定义析构逻辑。
- 真正的 teardown 发生在成员对象析构阶段:
- `m_cameraRenderer` 会关闭当前 runtime pipeline 和 object-id pass。
- `m_requestPlanner` 作为普通值成员按常规方式销毁。
- `SceneRenderer` 不拥有外部传入请求上的 `RenderPassSequence`,因此析构时不会回收这些外部序列对象。
## 调用方影响
- 即使 `SceneRenderer` 的析构函数是 `= default`,离开作用域时仍会触发内部 `CameraRenderer` 的资源释放路径。
- 任何此前通过 [GetPipeline](GetPipeline.md) 或 [GetPipelineAsset](GetPipelineAsset.md) 观察到的非拥有指针,都会在 `SceneRenderer` 销毁后失效。
## 测试覆盖
- `tests/Rendering/unit/test_camera_scene_renderer.cpp` 使用作用域退出断言了 `SceneRenderer` 内部持有的 pipeline 会在对象销毁时执行 `Shutdown()`
## 相关文档
- [SceneRenderer](SceneRenderer.md)
- [GetPipeline](GetPipeline.md)
- [Render](Render.md)

View File

@@ -0,0 +1,35 @@
# SceneRenderer::GetPipeline
返回当前场景渲染器正在使用的 runtime pipeline。
```cpp
RenderPipeline* GetPipeline() const;
```
## 返回值
- 返回内部 `m_cameraRenderer.GetPipeline()` 的结果。
## 当前语义
- 这是一个非拥有裸指针,只用于观察当前绑定的是哪一个 `RenderPipeline` 实例。
- 该指针可能指向:
- 手动注入的 runtime pipeline。
- 由当前 pipeline asset 创建出的 runtime pipeline。
- 在空指针回退路径中自动补出的默认 builtin forward pipeline。
- 调用 [SetPipeline](SetPipeline.md) 或 [SetPipelineAsset](SetPipelineAsset.md) 后,这个指针都可能变化。
## 调用方影响
- 不应跨生命周期长期缓存这个指针;`SceneRenderer` 销毁、替换 pipeline 或回退默认 pipeline 后,它都可能失效。
- 它也不是“可由外部 delete 的所有权句柄”;真正的持有者仍是内部 `CameraRenderer`
## 测试覆盖
- `tests/Rendering/unit/test_camera_scene_renderer.cpp` 覆盖了替换 pipeline 前后 `GetPipeline()` 返回值的变化,以及旧 pipeline 被 `Shutdown()` 的行为。
## 相关文档
- [SceneRenderer](SceneRenderer.md)
- [SetPipeline](SetPipeline.md)
- [GetPipelineAsset](GetPipelineAsset.md)

View File

@@ -0,0 +1,33 @@
# SceneRenderer::GetPipelineAsset
返回当前场景渲染器绑定的 pipeline asset。
```cpp
const RenderPipelineAsset* GetPipelineAsset() const;
```
## 返回值
- 返回内部 `m_cameraRenderer.GetPipelineAsset()` 的结果。
## 当前语义
- 这是一个非拥有观察指针,用来回答“当前 runtime pipeline 是由哪个 asset 工厂派生出来的”。
- 默认构造的 `SceneRenderer` 通常会返回默认 builtin forward pipeline asset。
- 如果最近一次切换是 [SetPipeline](SetPipeline.md) 且传入了非空 runtime pipeline这里会变成 `nullptr`,因为那条路径会清掉当前 asset 绑定。
- 如果 [SetPipelineAsset](SetPipelineAsset.md) 传入空指针,内部不会保留 `nullptr`,而是回退到默认 builtin forward asset。
## 调用方影响
- 这不是 `shared_ptr` 的外露别名,不提供所有权,也不保证在 `SceneRenderer` 生命周期之外继续有效。
- 对外部来说,它更适合做调试、状态展示或测试断言,而不适合做长期缓存键。
## 测试覆盖
- `tests/Rendering/unit/test_camera_scene_renderer.cpp` 覆盖了默认 asset、替换 asset以及替换 runtime pipeline 后 asset 观察值的变化。
## 相关文档
- [SceneRenderer](SceneRenderer.md)
- [SetPipelineAsset](SetPipelineAsset.md)
- [GetPipeline](GetPipeline.md)

View File

@@ -0,0 +1,63 @@
# SceneRenderer::Render
```cpp
bool Render(const CameraRenderRequest& request);
bool Render(const std::vector<CameraRenderRequest>& requests);
bool Render(
const Components::Scene& scene,
Components::CameraComponent* overrideCamera,
const RenderContext& context,
const RenderSurface& surface);
```
## 行为说明
`SceneRenderer` 当前提供三种提交入口。
### `Render(const CameraRenderRequest&)`
这是最薄的转发层,直接调用:
```cpp
m_cameraRenderer.Render(request)
```
### `Render(const std::vector<CameraRenderRequest>&)`
当前实现会:
1. 拒绝空数组。
2. 检查每个请求都必须 `IsValid()`
3. 复制一份数组并调用 `SceneRenderRequestUtils::SortCameraRenderRequests(...)` 做稳定排序。
4. 逐个转发给 `m_cameraRenderer.Render(request)`
5. 任一请求失败即返回 `false`
### `Render(const Components::Scene&, ...)`
这是便捷入口,等价于:
```cpp
return Render(BuildRenderRequests(scene, overrideCamera, context, surface));
```
因此它本身不直接做 scene extraction真正的 `RenderSceneExtractor` 调用发生在 `CameraRenderer::Render(...)` 内部。
## 返回值
- 所有需要执行的请求都成功完成时返回 `true`
- 请求数组为空、任一请求无效,或任一请求执行失败时返回 `false`
## 测试覆盖
`tests/Rendering/unit/test_camera_scene_renderer.cpp` 当前覆盖了:
- 多相机请求的排序与稳定性。
- `Render(scene, ...)` 的请求构建与提交链路。
- 手工提交请求数组时的排序规则。
## 相关文档
- [SceneRenderer](SceneRenderer.md)
- [BuildRenderRequests](BuildRenderRequests.md)
- [CameraRenderer](../CameraRenderer/CameraRenderer.md)
- [SceneRenderRequestUtils](../SceneRenderRequestUtils/SceneRenderRequestUtils.md)

View File

@@ -0,0 +1,119 @@
# SceneRenderer
**命名空间**: `XCEngine::Rendering`
**类型**: `class`
**头文件**: `XCEngine/Rendering/Execution/SceneRenderer.h`
**描述**: 场景级渲染编排入口。它负责构建和排序 `CameraRenderRequest`,再把每个请求转交给 [CameraRenderer](../CameraRenderer/CameraRenderer.md) 执行。
## 概览
`SceneRenderer` 当前不再自己持有 `RenderSceneExtractor` 或直接驱动主管线。它只维护两块运行时对象:
- `m_requestPlanner`:负责从 `Scene` 和可选 override camera 生成 `CameraRenderRequest` 列表。
- `m_cameraRenderer`负责真正执行单个相机请求包括场景提取、主管线提交、object-id pass以及 request 上挂接的 pre/post/overlay pass sequence。
这意味着当前的主链路已经拆成两层:
1. `SceneRenderer` 负责“这次要渲染哪些相机、按什么顺序、每个请求的 surface/render-area/clear-flags 是什么”。
2. `CameraRenderer` 负责“单个请求如何真正跑完”。
这条边界是当前 Rendering 模块里最值得保留的设计决定之一。
如果把相机规划和 request 执行重新揉回一个类里Editor 的 Scene View、object-id picking、overlay 注入和离屏渲染很快就会和主管线细节耦合到一起。
现在的拆法则让 `SceneRenderer` 更像一个稳定的编排入口:
-`Scene` 直接提交时,它负责生成 request
- 从外部手工提交 request 时,它负责复用同一排序规则
- 不管 request 来源是什么,真正执行都统一落到 `CameraRenderer`
## 当前执行路径
### `BuildRenderRequests(...)`
直接委托给 [SceneRenderRequestPlanner](../SceneRenderRequestPlanner/SceneRenderRequestPlanner.md)
```cpp
return m_requestPlanner.BuildRequests(scene, overrideCamera, context, surface);
```
### `Render(const Components::Scene&, ...)`
这是“从场景直接提交”的便捷入口,本质上等价于:
```cpp
return Render(BuildRenderRequests(scene, overrideCamera, context, surface));
```
### `Render(const std::vector<CameraRenderRequest>&)`
当前会:
1. 拒绝空请求数组。
2. 拒绝任何 `IsValid()` 为假的请求。
3. 复制一份请求数组,并通过 `SceneRenderRequestUtils::SortCameraRenderRequests(...)` 做稳定排序。
4. 依次调用 `m_cameraRenderer.Render(request)`
5. 任一请求失败就立即返回 `false`
这里不会额外改写 request 里的 `objectId` 或各类 pass sequence如果上层已经补好了这些字段`SceneRenderer` 只负责排序后转交执行。
这也是为什么手工 request 提交路径仍然会再次排序。当前实现明确认为“stack/depth 规则”属于 `SceneRenderer` 的稳定契约,而不是调用方各自维护的一套隐式约定。
### `Render(const CameraRenderRequest&)`
这是最薄的一层,直接转发到 `m_cameraRenderer.Render(request)`
## 构造与默认行为
- 默认构造通过默认构造的 `CameraRenderer` 获得默认主管线与默认 object-id pass。
- 传入 `std::unique_ptr<RenderPipeline>` 时,走“手动注入 runtime pipeline”路径。
- 传入 `std::shared_ptr<const RenderPipelineAsset>` 时,走“由 asset 创建 runtime pipeline”路径。
默认主管线的具体创建不在 `SceneRenderer` 内部硬编码,而是由 `CameraRenderer` 通过默认 [BuiltinForwardPipelineAsset](../Pipelines/BuiltinForwardPipelineAsset/BuiltinForwardPipelineAsset.md) 负责。
## 当前实现边界
- 不直接做 scene extraction真正的 `RenderSceneExtractor` 调用发生在 `CameraRenderer` 里。
- 不直接操作 `RenderPipeline` 的初始化或渲染细节;它只负责请求规划和排序。
- 不负责替 request 自动补 `objectId` 或各类 `RenderPassSequence`;这类附加阶段通常由 Editor 或其他上层调用方在提交前写入。
- 对手工提交的请求数组,会再次按相机优先级稳定排序,而不是按调用方原始顺序盲目执行。
## 测试覆盖
`tests/Rendering/unit/test_camera_scene_renderer.cpp` 当前验证了:
- `BuildRenderRequests()` 的多相机排序、override camera、clear-flags 和 viewport/render-area 解析。
- 手工提交请求数组时的排序和稳定性。
- `SetPipeline()` / `SetPipelineAsset()` 的转发、替换与 shutdown 行为。
这些测试锚点说明,`SceneRenderer` 当前不是一个“薄到没有语义”的转发器。它真正承担了 request planning 契约本身,包括:
- override camera 的回退语义
- base / overlay 排序
- `Auto` clear 的默认策略
- 手工 request 重新排序的稳定性
## 公开方法
| 方法 | 说明 |
|------|------|
| [Constructor](Constructor.md) | 构造 `SceneRenderer`,并决定 `CameraRenderer` 的主管线路径。 |
| [Destructor](Destructor.md) | 默认析构;真正的运行时清理由成员对象完成。 |
| [SetPipeline](SetPipeline.md) | 手动替换当前 runtime `RenderPipeline`。 |
| [SetPipelineAsset](SetPipelineAsset.md) | 通过 `RenderPipelineAsset` 重建当前 runtime `RenderPipeline`。 |
| [GetPipeline](GetPipeline.md) | 返回当前主管线的非拥有指针。 |
| [GetPipelineAsset](GetPipelineAsset.md) | 返回当前 pipeline asset 的非拥有指针。 |
| [BuildRenderRequests](BuildRenderRequests.md) | 生成当前场景对应的相机请求列表。 |
| [Render](Render.md) | 执行单个请求、请求数组,或从场景直接生成请求并执行。 |
## 相关文档
- [Rendering](../Rendering.md)
- [CameraRenderer](../CameraRenderer/CameraRenderer.md)
- [SceneRenderRequestPlanner](../SceneRenderRequestPlanner/SceneRenderRequestPlanner.md)
- [SceneRenderRequestUtils](../SceneRenderRequestUtils/SceneRenderRequestUtils.md)
- [RenderSceneExtractor](../RenderSceneExtractor/RenderSceneExtractor.md)
- [Camera Request Planning And Clear Rules](../../../_guides/Rendering/Camera-Request-Planning-And-Clear-Rules.md)

View File

@@ -0,0 +1,32 @@
# SceneRenderer::SetPipeline
```cpp
void SetPipeline(std::unique_ptr<RenderPipeline> pipeline);
```
## 行为说明
当前实现只是把调用转发给内部 `m_cameraRenderer`
```cpp
m_cameraRenderer.SetPipeline(std::move(pipeline));
```
## 当前语义
沿用 `CameraRenderer::SetPipeline()` 的规则:
- 当前绑定的 `RenderPipelineAsset` 会被清空。
- 被替换掉的旧 runtime pipeline 会先执行 `Shutdown()`
- 如果新传入的 `pipeline` 为空,内部会回退到默认 pipeline asset并重新创建默认主管线。
## 参数
- `pipeline` - 新的 runtime pipeline 所有权,可为空。
## 相关文档
- [SceneRenderer](SceneRenderer.md)
- [SetPipelineAsset](SetPipelineAsset.md)
- [GetPipeline](GetPipeline.md)
- [CameraRenderer::SetPipeline](../CameraRenderer/SetPipeline.md)

View File

@@ -0,0 +1,34 @@
# SceneRenderer::SetPipelineAsset
切换当前场景渲染器使用的 pipeline asset。
```cpp
void SetPipelineAsset(std::shared_ptr<const RenderPipelineAsset> pipelineAsset);
```
## 参数
- `pipelineAsset` - 目标 pipeline asset允许传入空指针。
## 当前语义
- 当前实现直接转发到内部 `m_cameraRenderer.SetPipelineAsset(...)`
- 如果传入 asset 非空,后续 runtime pipeline 会由该 asset 创建。
- 如果传入 asset 为空,内部会回退到默认 builtin forward pipeline asset而不是保留空绑定。
- 被替换掉的旧 runtime pipeline 会先执行 `Shutdown()`,再由新 asset 创建新实例。
## 调用方影响
- 调用之后,[GetPipelineAsset](GetPipelineAsset.md) 和 [GetPipeline](GetPipeline.md) 的返回值都可能变化。
- 任何此前缓存的旧 pipeline 指针都应视为潜在失效。
- 如果调用方只是想直接接管 runtime pipeline而不是保留 asset 工厂关系,应改用 [SetPipeline](SetPipeline.md)。
## 测试覆盖
- `tests/Rendering/unit/test_camera_scene_renderer.cpp` 验证了替换 asset 时旧 pipeline 会被 `Shutdown()`,并且新 asset 会创建新的 runtime pipeline 实例。
## 相关文档
- [SceneRenderer](SceneRenderer.md)
- [SetPipeline](SetPipeline.md)
- [GetPipelineAsset](GetPipelineAsset.md)