5.8 KiB
SceneRenderer
命名空间: XCEngine::Rendering
类型: class
头文件: XCEngine/Rendering/Execution/SceneRenderer.h
描述: 场景级渲染编排入口。它负责构建和排序 CameraRenderRequest,再把每个请求转交给 CameraRenderer 执行。
概览
SceneRenderer 当前不再自己持有 RenderSceneExtractor 或直接驱动主管线。它只维护两块运行时对象:
m_requestPlanner:负责从Scene和可选 override camera 生成CameraRenderRequest列表。m_cameraRenderer:负责真正执行单个相机请求,包括场景提取、主管线提交、object-id pass,以及 request 上挂接的 pre/post/overlay pass sequence。
这意味着当前的主链路已经拆成两层:
SceneRenderer负责“这次要渲染哪些相机、按什么顺序、每个请求的 surface/render-area/clear-flags 是什么”。CameraRenderer负责“单个请求如何真正跑完”。
这条边界是当前 Rendering 模块里最值得保留的设计决定之一。 如果把相机规划和 request 执行重新揉回一个类里,Editor 的 Scene View、object-id picking、overlay 注入和离屏渲染很快就会和主管线细节耦合到一起。
现在的拆法则让 SceneRenderer 更像一个稳定的编排入口:
- 从
Scene直接提交时,它负责生成 request - 从外部手工提交 request 时,它负责复用同一排序规则
- 不管 request 来源是什么,真正执行都统一落到
CameraRenderer
当前执行路径
BuildRenderRequests(...)
直接委托给 SceneRenderRequestPlanner:
return m_requestPlanner.BuildRequests(scene, overrideCamera, context, surface);
Render(const Components::Scene&, ...)
这是“从场景直接提交”的便捷入口,本质上等价于:
return Render(BuildRenderRequests(scene, overrideCamera, context, surface));
Render(const std::vector<CameraRenderRequest>&)
当前会:
- 拒绝空请求数组。
- 拒绝任何
IsValid()为假的请求。 - 复制一份请求数组,并通过
SceneRenderRequestUtils::SortCameraRenderRequests(...)做稳定排序。 - 依次调用
m_cameraRenderer.Render(request)。 - 任一请求失败就立即返回
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 负责。
当前实现边界
- 不直接做 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 排序
Autoclear 的默认策略- 手工 request 重新排序的稳定性
公开方法
| 方法 | 说明 |
|---|---|
| Constructor | 构造 SceneRenderer,并决定 CameraRenderer 的主管线路径。 |
| Destructor | 默认析构;真正的运行时清理由成员对象完成。 |
| SetPipeline | 手动替换当前 runtime RenderPipeline。 |
| SetPipelineAsset | 通过 RenderPipelineAsset 重建当前 runtime RenderPipeline。 |
| GetPipeline | 返回当前主管线的非拥有指针。 |
| GetPipelineAsset | 返回当前 pipeline asset 的非拥有指针。 |
| BuildRenderRequests | 生成当前场景对应的相机请求列表。 |
| Render | 执行单个请求、请求数组,或从场景直接生成请求并执行。 |