docs: sync scene renderer docs
This commit is contained in:
@@ -1,7 +1,5 @@
|
|||||||
# RenderSceneExtractor::Extract
|
# RenderSceneExtractor::Extract
|
||||||
|
|
||||||
从场景中提取当前帧要渲染的数据。
|
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
RenderSceneData Extract(
|
RenderSceneData Extract(
|
||||||
const Components::Scene& scene,
|
const Components::Scene& scene,
|
||||||
@@ -14,29 +12,33 @@ RenderSceneData Extract(
|
|||||||
|
|
||||||
当前实现会:
|
当前实现会:
|
||||||
|
|
||||||
1. 选择一台可用相机。
|
1. 调用 [SelectCamera](SelectCamera.md) 解析实际使用的相机。
|
||||||
2. 根据相机和视口尺寸构造 `RenderCameraData`。
|
2. 如果没有可用相机,直接返回空的 `RenderSceneData`。
|
||||||
3. 从场景根对象开始递归遍历层级。
|
3. 基于选中的相机和 viewport 尺寸生成 `RenderCameraData`。
|
||||||
4. 收集符合条件的 mesh 对象,输出 `VisibleRenderObject` 数组。
|
4. 从场景所有 root game object 开始递归收集 `visibleItems`。
|
||||||
|
5. 对 `visibleItems` 做稳定排序。
|
||||||
|
6. 提取主方向光到 `lighting`。
|
||||||
|
|
||||||
## 参数
|
## 参数
|
||||||
|
|
||||||
- `scene` - 要提取的场景。
|
- `scene` - 要提取的场景。
|
||||||
- `overrideCamera` - 显式指定的相机;若可用则优先级最高。
|
- `overrideCamera` - 可选的 override 相机;可用时具有最高优先级。
|
||||||
- `viewportWidth` - 当前视口宽度。
|
- `viewportWidth` - 当前 viewport 宽度。
|
||||||
- `viewportHeight` - 当前视口高度。
|
- `viewportHeight` - 当前 viewport 高度。
|
||||||
|
|
||||||
## 返回值
|
## 返回值
|
||||||
|
|
||||||
- 一份 `RenderSceneData`。
|
- 一份 `RenderSceneData`。
|
||||||
|
- 若没有可用相机,返回值中的 `camera` 为空,`visibleItems` 也为空。
|
||||||
|
|
||||||
## 当前实现说明
|
## 当前实现细节
|
||||||
|
|
||||||
- 当没有可用相机时,返回的 `RenderSceneData` 里 `camera == nullptr`。
|
- 当前会使用选中相机的 `GetCullingMask()` 过滤对象层。
|
||||||
- 透视相机使用 `Matrix4x4::Perspective`,正交相机使用 `Matrix4x4::Orthographic`。
|
- `visibleItems` 是当前真正的输出字段,不是旧文档里的 `visibleObjects`。
|
||||||
- 当前把 `view`、`projection` 和 `viewProjection` 都以转置形式写入结果。
|
- 排序时会按 `renderQueue` 和透明/非透明距离方向处理。
|
||||||
|
|
||||||
## 相关文档
|
## 相关文档
|
||||||
|
|
||||||
- [返回类型总览](RenderSceneExtractor.md)
|
- [RenderSceneExtractor](RenderSceneExtractor.md)
|
||||||
- [SceneRenderer::Render](../SceneRenderer/Render.md)
|
- [ExtractForCamera](ExtractForCamera.md)
|
||||||
|
- [SelectCamera](SelectCamera.md)
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# RenderSceneExtractor::ExtractForCamera
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
RenderSceneData ExtractForCamera(
|
||||||
|
const Components::Scene& scene,
|
||||||
|
Components::CameraComponent& camera,
|
||||||
|
uint32_t viewportWidth,
|
||||||
|
uint32_t viewportHeight) const;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 行为说明
|
||||||
|
|
||||||
|
和 [Extract](Extract.md) 相比,这个重载不会重新选择相机,而是要求调用方显式给出要使用的相机。
|
||||||
|
|
||||||
|
当前实现会:
|
||||||
|
|
||||||
|
1. 先检查给定相机是否可用。
|
||||||
|
2. 相机不可用时,直接返回空的 `RenderSceneData`。
|
||||||
|
3. 相机可用时,生成 `RenderCameraData`。
|
||||||
|
4. 按相机的 `cullingMask` 递归提取 `visibleItems`。
|
||||||
|
5. 对 `visibleItems` 做稳定排序,并提取主方向光。
|
||||||
|
|
||||||
|
## 参数
|
||||||
|
|
||||||
|
- `scene` - 要提取的场景。
|
||||||
|
- `camera` - 显式指定的相机。
|
||||||
|
- `viewportWidth` - 当前 viewport 宽度。
|
||||||
|
- `viewportHeight` - 当前 viewport 高度。
|
||||||
|
|
||||||
|
## 返回值
|
||||||
|
|
||||||
|
- 使用指定相机构建的 `RenderSceneData`。
|
||||||
|
- 如果相机不可用,返回空结果。
|
||||||
|
|
||||||
|
## 相关文档
|
||||||
|
|
||||||
|
- [RenderSceneExtractor](RenderSceneExtractor.md)
|
||||||
|
- [Extract](Extract.md)
|
||||||
|
- [SelectCamera](SelectCamera.md)
|
||||||
@@ -2,66 +2,85 @@
|
|||||||
|
|
||||||
**命名空间**: `XCEngine::Rendering`
|
**命名空间**: `XCEngine::Rendering`
|
||||||
|
|
||||||
**类型**: `class + struct`
|
**类型**: `class + related structs`
|
||||||
|
|
||||||
**头文件**: `XCEngine/Rendering/RenderSceneExtractor.h`
|
**头文件**: `XCEngine/Rendering/RenderSceneExtractor.h`
|
||||||
|
|
||||||
**描述**: 从 `Scene` 中挑选相机并收集可渲染 mesh 对象,输出渲染层使用的 `RenderSceneData`。
|
**描述**: 把 `Scene` 压平成渲染侧可消费的 `RenderSceneData`,负责相机选择、主方向光提取和 `visibleItems` 收集。
|
||||||
|
|
||||||
## 概述
|
## 概览
|
||||||
|
|
||||||
`RenderSceneExtractor` 是当前渲染架构里最接近“scene extraction”阶段的对象。
|
`RenderSceneExtractor` 处在“场景对象组织”和“单相机渲染提交”之间。它不负责真正发 draw call,而是把场景转换成一份更适合渲染阶段消费的数据:
|
||||||
|
|
||||||
它的职责不是绘制,而是把面向 gameplay / scene graph 的对象整理成渲染层更容易消费的数据:
|
- `camera`
|
||||||
|
- `cameraData`
|
||||||
|
- `lighting`
|
||||||
|
- `visibleItems`
|
||||||
|
|
||||||
- 一台要使用的相机
|
当前 `CameraRenderer` 会在执行单个 `CameraRenderRequest` 时调用它。
|
||||||
- 一份拍平后的 [RenderCameraData](../RenderCameraData/RenderCameraData.md)
|
|
||||||
- 一组 [VisibleRenderObject](../VisibleRenderObject/VisibleRenderObject.md)
|
|
||||||
|
|
||||||
这和商业引擎里把 scene traversal、visibility building、render packet generation 放在真正 draw submission 之前的设计是一致的。
|
|
||||||
|
|
||||||
## `RenderSceneData`
|
## `RenderSceneData`
|
||||||
|
|
||||||
| 字段 | 类型 | 说明 |
|
| 字段 | 类型 | 说明 |
|
||||||
|------|------|------|
|
|------|------|------|
|
||||||
| `camera` | `Components::CameraComponent*` | 选中的相机。 |
|
| `camera` | `Components::CameraComponent*` | 当前提取使用的相机。 |
|
||||||
| `cameraData` | `RenderCameraData` | 渲染阶段使用的拍平相机数据。 |
|
| `cameraData` | `RenderCameraData` | 由相机和 viewport 推导出的渲染相机数据。 |
|
||||||
| `visibleObjects` | `std::vector<VisibleRenderObject>` | 当前提取到的可见对象列表。 |
|
| `lighting` | `RenderLightingData` | 当前主方向光快照。 |
|
||||||
|
| `visibleItems` | `std::vector<VisibleRenderItem>` | 当前帧提取出的可绘制项列表。 |
|
||||||
|
|
||||||
`RenderSceneData::HasCamera()` 当前只是检查 `camera != nullptr`。
|
`RenderSceneData::HasCamera()` 当前只是检查 `camera != nullptr`。
|
||||||
|
|
||||||
## 当前提取规则
|
## 当前提取规则
|
||||||
|
|
||||||
相机选择当前按以下顺序执行:
|
### 相机
|
||||||
|
|
||||||
1. 如果 `overrideCamera` 可用,直接使用它。
|
- `SelectCamera()` 优先使用可用的 `overrideCamera`。
|
||||||
2. 否则从场景里找出 `IsPrimary()` 的可用相机,取 `depth` 最大者。
|
- 否则在场景里选出所有可用相机中的“最高深度 primary camera”。
|
||||||
3. 如果仍没有,则退回到第一个可用相机。
|
- 如果没有 primary,则回退到第一个可用相机。
|
||||||
|
|
||||||
对象提取当前只要求:
|
### 光照
|
||||||
|
|
||||||
- `GameObject` 处于 `IsActiveInHierarchy()`
|
- 只提取可用的方向光。
|
||||||
- 同时有 `MeshFilterComponent` 和 `MeshRendererComponent`
|
- 当前只保留一盏“主方向光”。
|
||||||
- 两个组件都启用
|
- 选择规则是“强度最高的可用方向光”。
|
||||||
- `MeshFilterComponent` 提供的 mesh 非空且 `IsValid()`
|
|
||||||
|
|
||||||
## 当前实现限制
|
### 可绘制项
|
||||||
|
|
||||||
- 当前没有 frustum culling。
|
- 只递归遍历 `IsActiveInHierarchy()` 的对象。
|
||||||
- 当前没有 render layer 过滤。
|
- 先按相机 `cullingMask` 过滤 `GameObject` 层。
|
||||||
- 当前没有透明/不透明分类、排序或 batching。
|
- 对通过过滤的对象,调用 `AppendRenderItemsForGameObject(...)` 展开成一个或多个 `VisibleRenderItem`。
|
||||||
- 当前不会读取 `castShadows` / `receiveShadows`。
|
|
||||||
- 当前把“visible”理解为“满足基本组件条件且在激活层级中”,而不是严格意义上的屏幕可见。
|
因此当前 `visibleItems` 不只是旧说法里的“visible object 列表”,而是已经展开过材质、section、render queue 和相机距离的渲染项数组。
|
||||||
|
|
||||||
|
## 当前排序规则
|
||||||
|
|
||||||
|
提取完成后,`visibleItems` 会做一次 `std::stable_sort`:
|
||||||
|
|
||||||
|
1. `renderQueue` 小的排前面。
|
||||||
|
2. 如果是透明队列,按 `cameraDistanceSq` 从远到近。
|
||||||
|
3. 否则按 `cameraDistanceSq` 从近到远。
|
||||||
|
4. 最后再按 `gameObject` 指针和 `sectionIndex` 打破平局。
|
||||||
|
|
||||||
|
这让 opaque 与 transparent 的默认排序方向和当前 `RenderMaterialUtility` 的队列语义保持一致。
|
||||||
|
|
||||||
|
## 当前限制
|
||||||
|
|
||||||
|
- 没有 frustum culling。
|
||||||
|
- 没有 occlusion culling。
|
||||||
|
- 没有 batching 或 instancing。
|
||||||
|
- 只提取单个主方向光,不保留多光源列表。
|
||||||
|
|
||||||
## 公开方法
|
## 公开方法
|
||||||
|
|
||||||
| 方法 | 说明 |
|
| 方法 | 说明 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| [Extract](Extract.md) | 从场景中提取渲染数据。 |
|
| [Extract](Extract.md) | 自动选择相机并提取 `RenderSceneData`。 |
|
||||||
|
| [ExtractForCamera](ExtractForCamera.md) | 使用显式给定相机提取 `RenderSceneData`。 |
|
||||||
|
| [SelectCamera](SelectCamera.md) | 按当前规则选择可用相机。 |
|
||||||
|
|
||||||
## 相关文档
|
## 相关文档
|
||||||
|
|
||||||
- [当前模块](../Rendering.md)
|
- [Rendering](../Rendering.md)
|
||||||
- [RenderCameraData](../RenderCameraData/RenderCameraData.md)
|
|
||||||
- [VisibleRenderObject](../VisibleRenderObject/VisibleRenderObject.md)
|
- [VisibleRenderObject](../VisibleRenderObject/VisibleRenderObject.md)
|
||||||
- [SceneRenderer](../SceneRenderer/SceneRenderer.md)
|
- [CameraRenderer](../CameraRenderer/CameraRenderer.md)
|
||||||
|
- [Scene Extraction And Builtin Forward Pipeline](../../../_guides/Rendering/Scene-Extraction-And-Builtin-Forward-Pipeline.md)
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# RenderSceneExtractor::SelectCamera
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
Components::CameraComponent* SelectCamera(
|
||||||
|
const Components::Scene& scene,
|
||||||
|
Components::CameraComponent* overrideCamera) const;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 行为说明
|
||||||
|
|
||||||
|
当前相机选择规则是:
|
||||||
|
|
||||||
|
1. 如果 `overrideCamera` 可用,直接返回它。
|
||||||
|
2. 否则在场景相机里挑出所有可用的 primary camera,并返回 `depth` 最高的那一台。
|
||||||
|
3. 如果没有可用 primary camera,则返回第一台可用相机。
|
||||||
|
4. 如果场景里没有任何可用相机,返回 `nullptr`。
|
||||||
|
|
||||||
|
## “可用相机”的当前定义
|
||||||
|
|
||||||
|
相机必须同时满足:
|
||||||
|
|
||||||
|
- 指针非空
|
||||||
|
- `camera->IsEnabled()`
|
||||||
|
- `camera->GetGameObject() != nullptr`
|
||||||
|
- 相机所在 `GameObject` 处于 `IsActiveInHierarchy()`
|
||||||
|
|
||||||
|
## 返回值
|
||||||
|
|
||||||
|
- 当前规则下选中的相机。
|
||||||
|
- 找不到可用相机时返回 `nullptr`。
|
||||||
|
|
||||||
|
## 相关文档
|
||||||
|
|
||||||
|
- [RenderSceneExtractor](RenderSceneExtractor.md)
|
||||||
|
- [Extract](Extract.md)
|
||||||
|
- [SceneRenderer::BuildRenderRequests](../SceneRenderer/BuildRenderRequests.md)
|
||||||
@@ -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)
|
||||||
@@ -1,19 +1,27 @@
|
|||||||
# SceneRenderer::SceneRenderer
|
# SceneRenderer::SceneRenderer
|
||||||
|
|
||||||
构造场景渲染器。
|
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
SceneRenderer();
|
SceneRenderer();
|
||||||
explicit SceneRenderer(std::unique_ptr<RenderPipeline> pipeline);
|
explicit SceneRenderer(std::unique_ptr<RenderPipeline> pipeline);
|
||||||
|
explicit SceneRenderer(std::shared_ptr<const RenderPipelineAsset> pipelineAsset);
|
||||||
```
|
```
|
||||||
|
|
||||||
## 行为说明
|
## 行为说明
|
||||||
|
|
||||||
- 默认构造函数会创建一个 `BuiltinForwardPipeline`。
|
三个构造路径都只是决定内部 `m_cameraRenderer` 如何初始化:
|
||||||
- 传入 `pipeline` 的重载会接管该对象所有权。
|
|
||||||
- 如果传入空指针,当前实现会退回到 `BuiltinForwardPipeline`。
|
- 默认构造:使用默认构造的 `CameraRenderer`。
|
||||||
|
- `std::unique_ptr<RenderPipeline>`:把手工注入的 runtime pipeline 交给 `CameraRenderer`。
|
||||||
|
- `std::shared_ptr<const RenderPipelineAsset>`:让 `CameraRenderer` 从 asset 创建 runtime pipeline。
|
||||||
|
|
||||||
|
## 当前实现细节
|
||||||
|
|
||||||
|
- 默认构造函数本身没有额外逻辑,`SceneRenderer::SceneRenderer() = default;`。
|
||||||
|
- 如果传入的 `pipeline` 为空,`CameraRenderer` 内部会回退到默认 pipeline asset 并重新创建默认主管线。
|
||||||
|
- 如果传入的 `pipelineAsset` 为空,`CameraRenderer` 也会回退到默认 [BuiltinForwardPipelineAsset](../Pipelines/BuiltinForwardPipelineAsset/BuiltinForwardPipelineAsset.md)。
|
||||||
|
|
||||||
## 相关文档
|
## 相关文档
|
||||||
|
|
||||||
- [返回类型总览](SceneRenderer.md)
|
- [SceneRenderer](SceneRenderer.md)
|
||||||
- [SetPipeline](SetPipeline.md)
|
- [SetPipeline](SetPipeline.md)
|
||||||
|
- [SetPipelineAsset](SetPipelineAsset.md)
|
||||||
|
|||||||
@@ -1,22 +1,19 @@
|
|||||||
# SceneRenderer::~SceneRenderer
|
# SceneRenderer::~SceneRenderer
|
||||||
|
|
||||||
销毁场景渲染器。
|
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
~SceneRenderer();
|
~SceneRenderer() = default;
|
||||||
```
|
```
|
||||||
|
|
||||||
## 行为说明
|
## 行为说明
|
||||||
|
|
||||||
当前实现会在析构时检查当前 pipeline 是否存在;若存在,就调用其 `Shutdown()`。
|
`SceneRenderer` 自身没有自定义析构逻辑。真正的资源关闭发生在成员析构阶段:
|
||||||
|
|
||||||
## 注意事项
|
- `m_cameraRenderer` 会在自身析构里关闭当前主管线、object-id pass 和 builtin post-process builder。
|
||||||
|
- `m_requestPlanner` 按普通值成员销毁。
|
||||||
|
|
||||||
- 当前析构不会显式 `reset()` pipeline 之前做更多状态同步。
|
因此当前析构语义是“把 teardown 责任完全交给内部 `CameraRenderer`”,而不是在 `SceneRenderer` 层重复写一套 shutdown 流程。
|
||||||
- 因为 `unique_ptr` 随后会继续销毁对象,所以派生 pipeline 自身析构也会继续执行。
|
|
||||||
|
|
||||||
## 相关文档
|
## 相关文档
|
||||||
|
|
||||||
- [返回类型总览](SceneRenderer.md)
|
- [SceneRenderer](SceneRenderer.md)
|
||||||
- [SetPipeline](SetPipeline.md)
|
- [CameraRenderer](../CameraRenderer/CameraRenderer.md)
|
||||||
- [RenderPipeline::Shutdown](../RenderPipeline/Shutdown.md)
|
|
||||||
|
|||||||
@@ -1,21 +1,25 @@
|
|||||||
# SceneRenderer::GetPipeline
|
# SceneRenderer::GetPipeline
|
||||||
|
|
||||||
获取当前渲染管线指针。
|
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
RenderPipeline* GetPipeline() const;
|
RenderPipeline* GetPipeline() const;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 行为说明
|
||||||
|
|
||||||
|
直接返回内部 `m_cameraRenderer.GetPipeline()` 的结果。
|
||||||
|
|
||||||
## 返回值
|
## 返回值
|
||||||
|
|
||||||
- 返回当前持有的 `RenderPipeline*`。
|
- 当前主管线的非拥有指针。
|
||||||
|
|
||||||
## 注意事项
|
## 注意事项
|
||||||
|
|
||||||
- 这是非拥有指针。
|
- 这个指针既可能指向手工注入的 runtime pipeline,也可能指向由 pipeline asset 创建的实例。
|
||||||
- 默认构造下通常会返回 `BuiltinForwardPipeline` 实例。
|
- 调用 [SetPipeline](SetPipeline.md) 或 [SetPipelineAsset](SetPipelineAsset.md) 后,返回的对象可能变化。
|
||||||
|
- 默认构造下通常会返回由默认 [BuiltinForwardPipelineAsset](../Pipelines/BuiltinForwardPipelineAsset/BuiltinForwardPipelineAsset.md) 创建的主管线实例。
|
||||||
|
|
||||||
## 相关文档
|
## 相关文档
|
||||||
|
|
||||||
- [返回类型总览](SceneRenderer.md)
|
- [SceneRenderer](SceneRenderer.md)
|
||||||
- [SetPipeline](SetPipeline.md)
|
- [SetPipeline](SetPipeline.md)
|
||||||
|
- [GetPipelineAsset](GetPipelineAsset.md)
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# SceneRenderer::GetPipelineAsset
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
const RenderPipelineAsset* GetPipelineAsset() const;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 行为说明
|
||||||
|
|
||||||
|
直接返回内部 `m_cameraRenderer.GetPipelineAsset()` 的结果。
|
||||||
|
|
||||||
|
## 返回值
|
||||||
|
|
||||||
|
- 当前绑定的 pipeline asset 的非拥有指针。
|
||||||
|
- 如果最近一次切换是通过 [SetPipeline](SetPipeline.md) 手工注入 runtime pipeline,则这里可能为 `nullptr`。
|
||||||
|
|
||||||
|
## 当前默认行为
|
||||||
|
|
||||||
|
默认构造的 `SceneRenderer` 通常会返回默认 [BuiltinForwardPipelineAsset](../Pipelines/BuiltinForwardPipelineAsset/BuiltinForwardPipelineAsset.md)。
|
||||||
|
|
||||||
|
## 相关文档
|
||||||
|
|
||||||
|
- [SceneRenderer](SceneRenderer.md)
|
||||||
|
- [SetPipelineAsset](SetPipelineAsset.md)
|
||||||
|
- [GetPipeline](GetPipeline.md)
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
# SceneRenderer::Render
|
# SceneRenderer::Render
|
||||||
|
|
||||||
渲染一个场景。
|
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
|
bool Render(const CameraRenderRequest& request);
|
||||||
|
bool Render(const std::vector<CameraRenderRequest>& requests);
|
||||||
bool Render(
|
bool Render(
|
||||||
const Components::Scene& scene,
|
const Components::Scene& scene,
|
||||||
Components::CameraComponent* overrideCamera,
|
Components::CameraComponent* overrideCamera,
|
||||||
@@ -12,27 +12,52 @@ bool Render(
|
|||||||
|
|
||||||
## 行为说明
|
## 行为说明
|
||||||
|
|
||||||
|
`SceneRenderer` 当前提供三种提交入口。
|
||||||
|
|
||||||
|
### `Render(const CameraRenderRequest&)`
|
||||||
|
|
||||||
|
这是最薄的转发层,直接调用:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
m_cameraRenderer.Render(request)
|
||||||
|
```
|
||||||
|
|
||||||
|
### `Render(const std::vector<CameraRenderRequest>&)`
|
||||||
|
|
||||||
当前实现会:
|
当前实现会:
|
||||||
|
|
||||||
1. 检查 `context.IsValid()` 且当前 pipeline 非空。
|
1. 拒绝空数组。
|
||||||
2. 调用 `RenderSceneExtractor::Extract()` 生成 `RenderSceneData`。
|
2. 检查每个请求都必须 `IsValid()`。
|
||||||
3. 如果没有可用相机,直接返回 `false`。
|
3. 复制一份数组并调用 `SceneRenderRequestUtils::SortCameraRenderRequests(...)` 做稳定排序。
|
||||||
4. 调用当前 pipeline 的 `Render()` 执行真正绘制。
|
4. 逐个转发给 `m_cameraRenderer.Render(request)`。
|
||||||
|
5. 任一请求失败即返回 `false`。
|
||||||
|
|
||||||
## 参数
|
### `Render(const Components::Scene&, ...)`
|
||||||
|
|
||||||
- `scene` - 要渲染的场景。
|
这是便捷入口,等价于:
|
||||||
- `overrideCamera` - 可选的覆盖相机。
|
|
||||||
- `context` - 当前渲染上下文。
|
```cpp
|
||||||
- `surface` - 当前目标表面。
|
return Render(BuildRenderRequests(scene, overrideCamera, context, surface));
|
||||||
|
```
|
||||||
|
|
||||||
|
因此它本身不直接做 scene extraction;真正的 `RenderSceneExtractor` 调用发生在 `CameraRenderer::Render(...)` 内部。
|
||||||
|
|
||||||
## 返回值
|
## 返回值
|
||||||
|
|
||||||
- 渲染成功返回 `true`。
|
- 所有需要执行的请求都成功完成时返回 `true`。
|
||||||
- 若上下文无效、没有 pipeline 或没有可用相机,则返回 `false`。
|
- 请求数组为空、任一请求无效,或任一请求执行失败时返回 `false`。
|
||||||
|
|
||||||
|
## 测试覆盖
|
||||||
|
|
||||||
|
`tests/Rendering/unit/test_camera_scene_renderer.cpp` 当前覆盖了:
|
||||||
|
|
||||||
|
- 多相机请求的排序与稳定性。
|
||||||
|
- `Render(scene, ...)` 的请求构建与提交链路。
|
||||||
|
- 手工提交请求数组时的排序规则。
|
||||||
|
|
||||||
## 相关文档
|
## 相关文档
|
||||||
|
|
||||||
- [返回类型总览](SceneRenderer.md)
|
- [SceneRenderer](SceneRenderer.md)
|
||||||
- [RenderSceneExtractor::Extract](../RenderSceneExtractor/Extract.md)
|
- [BuildRenderRequests](BuildRenderRequests.md)
|
||||||
- [RenderPipeline::Render](../RenderPipeline/Render.md)
|
- [CameraRenderer](../CameraRenderer/CameraRenderer.md)
|
||||||
|
- [SceneRenderRequestUtils](../SceneRenderRequestUtils/SceneRenderRequestUtils.md)
|
||||||
|
|||||||
@@ -6,41 +6,91 @@
|
|||||||
|
|
||||||
**头文件**: `XCEngine/Rendering/SceneRenderer.h`
|
**头文件**: `XCEngine/Rendering/SceneRenderer.h`
|
||||||
|
|
||||||
**描述**: 组织一帧场景渲染流程,负责 scene extraction,并把结果交给当前 `RenderPipeline`。
|
**描述**: 场景级渲染编排入口。它负责构建和排序 `CameraRenderRequest`,再把每个请求转交给 [CameraRenderer](../CameraRenderer/CameraRenderer.md) 执行。
|
||||||
|
|
||||||
## 概述
|
## 概览
|
||||||
|
|
||||||
`SceneRenderer` 是当前渲染模块的主入口。它把“提取场景数据”和“执行具体渲染”两步串起来:
|
`SceneRenderer` 当前不再自己持有 `RenderSceneExtractor` 或直接驱动主管线。它只维护两块运行时对象:
|
||||||
|
|
||||||
- 内部持有一个 [RenderSceneExtractor](../RenderSceneExtractor/RenderSceneExtractor.md)
|
- `m_requestPlanner`:负责从 `Scene` 和可选 override camera 生成 `CameraRenderRequest` 列表。
|
||||||
- 内部持有一个当前使用的 [RenderPipeline](../RenderPipeline/RenderPipeline.md)
|
- `m_cameraRenderer`:负责真正执行单个相机请求,包括场景提取、主管线提交、object-id pass 和 builtin post-process。
|
||||||
|
|
||||||
默认情况下,它会创建 [BuiltinForwardPipeline](../Pipelines/BuiltinForwardPipeline/BuiltinForwardPipeline.md)。
|
这意味着当前的主链路已经拆成两层:
|
||||||
|
|
||||||
|
1. `SceneRenderer` 负责“这次要渲染哪些相机、按什么顺序、每个请求的 surface/render-area/clear-flags 是什么”。
|
||||||
|
2. `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`。
|
||||||
|
|
||||||
|
### `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) 负责。
|
||||||
|
|
||||||
## 当前实现边界
|
## 当前实现边界
|
||||||
|
|
||||||
- 默认构造会直接创建 `BuiltinForwardPipeline`。
|
- 不直接做 scene extraction;真正的 `RenderSceneExtractor` 调用发生在 `CameraRenderer` 里。
|
||||||
- 传入空 pipeline 时,构造函数和 [SetPipeline](SetPipeline.md) 都会退回到 `BuiltinForwardPipeline`。
|
- 不直接操作 `RenderPipeline` 的初始化或渲染细节;它只负责请求规划和排序。
|
||||||
- 析构时如果持有 pipeline,会调用其 `Shutdown()`。
|
- 对手工提交的请求数组,会再次按相机优先级稳定排序,而不是按调用方原始顺序盲目执行。
|
||||||
- [Render](Render.md) 当前只在运行时触发 pipeline 的 `Render()`,并不会显式先调用 `Initialize()`;默认前向管线靠内部 `EnsureInitialized()` 自己兜底。
|
|
||||||
|
## 测试覆盖
|
||||||
|
|
||||||
|
`tests/Rendering/unit/test_camera_scene_renderer.cpp` 当前验证了:
|
||||||
|
|
||||||
|
- `BuildRenderRequests()` 的多相机排序、override camera、clear-flags 和 viewport/render-area 解析。
|
||||||
|
- 手工提交请求数组时的排序和稳定性。
|
||||||
|
- `SetPipeline()` / `SetPipelineAsset()` 的转发、替换与 shutdown 行为。
|
||||||
|
|
||||||
## 公开方法
|
## 公开方法
|
||||||
|
|
||||||
| 方法 | 说明 |
|
| 方法 | 说明 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| [Constructor](Constructor.md) | 构造场景渲染器。 |
|
| [Constructor](Constructor.md) | 构造 `SceneRenderer`,并决定 `CameraRenderer` 的主管线路径。 |
|
||||||
| [Destructor](Destructor.md) | 析构时关闭当前管线。 |
|
| [Destructor](Destructor.md) | 默认析构;真正的运行时清理由成员对象完成。 |
|
||||||
| [SetPipeline](SetPipeline.md) | 替换当前渲染管线。 |
|
| [SetPipeline](SetPipeline.md) | 手动替换当前 runtime `RenderPipeline`。 |
|
||||||
| [GetPipeline](GetPipeline.md) | 获取当前管线指针。 |
|
| [SetPipelineAsset](SetPipelineAsset.md) | 通过 `RenderPipelineAsset` 重建当前 runtime `RenderPipeline`。 |
|
||||||
| [Render](Render.md) | 渲染一个场景。 |
|
| [GetPipeline](GetPipeline.md) | 返回当前主管线的非拥有指针。 |
|
||||||
|
| [GetPipelineAsset](GetPipelineAsset.md) | 返回当前 pipeline asset 的非拥有指针。 |
|
||||||
## 设计说明
|
| [BuildRenderRequests](BuildRenderRequests.md) | 生成当前场景对应的相机请求列表。 |
|
||||||
|
| [Render](Render.md) | 执行单个请求、请求数组,或从场景直接生成请求并执行。 |
|
||||||
把 `SceneRenderer` 保持得足够薄,是一个正确方向。真正复杂的渲染逻辑应该沉到 pipeline,而不是让 renderer 主入口变成一坨硬编码流程。
|
|
||||||
|
|
||||||
## 相关文档
|
## 相关文档
|
||||||
|
|
||||||
- [当前模块](../Rendering.md)
|
- [Rendering](../Rendering.md)
|
||||||
|
- [CameraRenderer](../CameraRenderer/CameraRenderer.md)
|
||||||
|
- [SceneRenderRequestPlanner](../SceneRenderRequestPlanner/SceneRenderRequestPlanner.md)
|
||||||
|
- [SceneRenderRequestUtils](../SceneRenderRequestUtils/SceneRenderRequestUtils.md)
|
||||||
- [RenderSceneExtractor](../RenderSceneExtractor/RenderSceneExtractor.md)
|
- [RenderSceneExtractor](../RenderSceneExtractor/RenderSceneExtractor.md)
|
||||||
- [RenderPipeline](../RenderPipeline/RenderPipeline.md)
|
|
||||||
- [BuiltinForwardPipeline](../Pipelines/BuiltinForwardPipeline/BuiltinForwardPipeline.md)
|
|
||||||
|
|||||||
@@ -1,25 +1,32 @@
|
|||||||
# SceneRenderer::SetPipeline
|
# SceneRenderer::SetPipeline
|
||||||
|
|
||||||
替换当前使用的渲染管线。
|
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
void SetPipeline(std::unique_ptr<RenderPipeline> pipeline);
|
void SetPipeline(std::unique_ptr<RenderPipeline> pipeline);
|
||||||
```
|
```
|
||||||
|
|
||||||
## 行为说明
|
## 行为说明
|
||||||
|
|
||||||
当前实现会:
|
当前实现只是把调用转发给内部 `m_cameraRenderer`:
|
||||||
|
|
||||||
1. 若已有 pipeline,则先调用其 `Shutdown()`。
|
```cpp
|
||||||
2. 用新传入的 `unique_ptr` 替换当前 pipeline。
|
m_cameraRenderer.SetPipeline(std::move(pipeline));
|
||||||
3. 如果新指针为空,则自动退回到 `BuiltinForwardPipeline`。
|
```
|
||||||
|
|
||||||
|
## 当前语义
|
||||||
|
|
||||||
|
沿用 `CameraRenderer::SetPipeline()` 的规则:
|
||||||
|
|
||||||
|
- 当前绑定的 `RenderPipelineAsset` 会被清空。
|
||||||
|
- 被替换掉的旧 runtime pipeline 会先执行 `Shutdown()`。
|
||||||
|
- 如果新传入的 `pipeline` 为空,内部会回退到默认 pipeline asset,并重新创建默认主管线。
|
||||||
|
|
||||||
## 参数
|
## 参数
|
||||||
|
|
||||||
- `pipeline` - 新的渲染管线实例。
|
- `pipeline` - 新的 runtime pipeline 所有权,可为空。
|
||||||
|
|
||||||
## 相关文档
|
## 相关文档
|
||||||
|
|
||||||
- [返回类型总览](SceneRenderer.md)
|
- [SceneRenderer](SceneRenderer.md)
|
||||||
|
- [SetPipelineAsset](SetPipelineAsset.md)
|
||||||
- [GetPipeline](GetPipeline.md)
|
- [GetPipeline](GetPipeline.md)
|
||||||
- [BuiltinForwardPipeline](../Pipelines/BuiltinForwardPipeline/BuiltinForwardPipeline.md)
|
- [CameraRenderer::SetPipeline](../CameraRenderer/SetPipeline.md)
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
# SceneRenderer::SetPipelineAsset
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void SetPipelineAsset(std::shared_ptr<const RenderPipelineAsset> pipelineAsset);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 行为说明
|
||||||
|
|
||||||
|
当前实现直接转发到内部 `m_cameraRenderer.SetPipelineAsset(...)`。
|
||||||
|
|
||||||
|
## 当前语义
|
||||||
|
|
||||||
|
- 如果传入 asset 非空,后续主管线实例来自这个 asset。
|
||||||
|
- 如果传入 asset 为空,会回退到默认 [BuiltinForwardPipelineAsset](../Pipelines/BuiltinForwardPipelineAsset/BuiltinForwardPipelineAsset.md)。
|
||||||
|
- 被替换掉的旧 runtime pipeline 会先执行 `Shutdown()`,再由新 asset 创建新的实例。
|
||||||
|
|
||||||
|
## 参数
|
||||||
|
|
||||||
|
- `pipelineAsset` - 当前主管线工厂,可为空。
|
||||||
|
|
||||||
|
## 相关文档
|
||||||
|
|
||||||
|
- [SceneRenderer](SceneRenderer.md)
|
||||||
|
- [SetPipeline](SetPipeline.md)
|
||||||
|
- [GetPipelineAsset](GetPipelineAsset.md)
|
||||||
|
- [CameraRenderer::SetPipelineAsset](../CameraRenderer/SetPipelineAsset.md)
|
||||||
@@ -2,36 +2,59 @@
|
|||||||
|
|
||||||
**命名空间**: `XCEngine::Rendering`
|
**命名空间**: `XCEngine::Rendering`
|
||||||
|
|
||||||
**类型**: `struct`
|
**类型**: `struct alias`
|
||||||
|
|
||||||
**头文件**: `XCEngine/Rendering/VisibleRenderObject.h`
|
**头文件**: `XCEngine/Rendering/VisibleRenderObject.h`
|
||||||
|
|
||||||
**描述**: 表示经过 scene extraction 后、当前帧准备交给渲染管线处理的一个可绘制对象。
|
**描述**: `VisibleRenderObject` 当前只是 `VisibleRenderItem` 的兼容别名。它表示 scene extraction 之后交给渲染阶段消费的一条可绘制项记录。
|
||||||
|
|
||||||
## 概述
|
## 概览
|
||||||
|
|
||||||
`VisibleRenderObject` 的价值,在于把场景对象、组件引用和绘制所需的最核心数据打包在一起。
|
头文件里的真实结构名已经是 `VisibleRenderItem`:
|
||||||
|
|
||||||
它当前没有变成更重的 render proxy 或 render packet,而是保持为非常轻量的桥接结构。这对当前引擎阶段是合理的。
|
```cpp
|
||||||
|
using VisibleRenderObject = VisibleRenderItem;
|
||||||
|
```
|
||||||
|
|
||||||
## 字段
|
因此这页保留的是历史命名入口,但语义应按当前 `VisibleRenderItem` 来理解。它不再只是“一个 mesh 对象”,而是已经带上材质槽位、section 信息、render queue 和相机距离的渲染项。
|
||||||
|
|
||||||
|
## 当前字段
|
||||||
|
|
||||||
| 字段 | 类型 | 说明 |
|
| 字段 | 类型 | 说明 |
|
||||||
|------|------|------|
|
|------|------|------|
|
||||||
| `gameObject` | `Components::GameObject*` | 原始场景对象。 |
|
| `gameObject` | `Components::GameObject*` | 来源场景对象。 |
|
||||||
| `meshFilter` | `Components::MeshFilterComponent*` | 提供 mesh 的组件。 |
|
| `meshFilter` | `Components::MeshFilterComponent*` | 提供 mesh 引用的组件。 |
|
||||||
| `meshRenderer` | `Components::MeshRendererComponent*` | 提供材质与渲染设置的组件。 |
|
| `meshRenderer` | `Components::MeshRendererComponent*` | 提供材质与渲染状态的组件。 |
|
||||||
| `mesh` | `Resources::Mesh*` | 当前要绘制的 mesh。 |
|
| `mesh` | `Resources::Mesh*` | 当前要绘制的 mesh。 |
|
||||||
| `localToWorld` | `Math::Matrix4x4` | 当前对象的局部到世界矩阵。 |
|
| `material` | `const Resources::Material*` | 当前解析出的材质指针,可为空。 |
|
||||||
|
| `materialIndex` | `Core::uint32` | 当前材质槽位索引。 |
|
||||||
|
| `sectionIndex` | `Core::uint32` | 当前 section 索引。 |
|
||||||
|
| `hasSection` | `bool` | 当前项是否绑定到特定 section。 |
|
||||||
|
| `renderQueue` | `Core::int32` | 当前项的渲染队列。 |
|
||||||
|
| `cameraDistanceSq` | `float` | 到当前相机的距离平方,用于排序。 |
|
||||||
|
| `localToWorld` | `Math::Matrix4x4` | 当前项的世界变换。 |
|
||||||
|
|
||||||
## 当前实现说明
|
## 当前生成方式
|
||||||
|
|
||||||
- 该结构由 [RenderSceneExtractor](../RenderSceneExtractor/RenderSceneExtractor.md) 填充。
|
- [RenderSceneExtractor](../RenderSceneExtractor/RenderSceneExtractor.md) 会递归遍历场景并调用 `AppendRenderItemsForGameObject(...)`。
|
||||||
- 当前 `localToWorld` 直接来自 `GameObject->GetTransform()->GetLocalToWorldMatrix()`。
|
- 同一个 `GameObject` 可能展开成多个 `VisibleRenderItem`,例如一个 mesh 有多个 section 时。
|
||||||
- 当前还没有把材质、排序 key、render queue、bounds 等更完整的渲染包信息放进来。
|
- `material`、`materialIndex`、`renderQueue` 和 `cameraDistanceSq` 都在提取阶段就已经写入,后续主管线不必再回到场景层重新推导。
|
||||||
|
|
||||||
|
## 当前使用位置
|
||||||
|
|
||||||
|
- `RenderSceneExtractor` 输出 `RenderSceneData::visibleItems`。
|
||||||
|
- `BuiltinForwardPipeline` 遍历这些项并决定 shader/pass、descriptor set 和 draw call。
|
||||||
|
- `BuiltinObjectIdPass` 也复用同一批 `visibleItems` 做 object-id 绘制。
|
||||||
|
|
||||||
|
## 当前限制
|
||||||
|
|
||||||
|
- 当前仍是轻量运行时结构,不是长期缓存的 render proxy。
|
||||||
|
- `cameraDistanceSq` 只是当前相机视角下的一次性排序辅助数据。
|
||||||
|
- 兼容别名 `VisibleRenderObject` 仍保留,但新文档和新实现都应优先使用 `VisibleRenderItem` 这个名称。
|
||||||
|
|
||||||
## 相关文档
|
## 相关文档
|
||||||
|
|
||||||
- [当前模块](../Rendering.md)
|
- [Rendering](../Rendering.md)
|
||||||
- [RenderSceneExtractor](../RenderSceneExtractor/RenderSceneExtractor.md)
|
- [RenderSceneExtractor](../RenderSceneExtractor/RenderSceneExtractor.md)
|
||||||
|
- [RenderSceneUtility](../RenderSceneUtility/RenderSceneUtility.md)
|
||||||
- [BuiltinForwardPipeline](../Pipelines/BuiltinForwardPipeline/BuiltinForwardPipeline.md)
|
- [BuiltinForwardPipeline](../Pipelines/BuiltinForwardPipeline/BuiltinForwardPipeline.md)
|
||||||
|
|||||||
Reference in New Issue
Block a user