渲染图:渲染的根调度
在 0.19 中,Bevy 的"渲染图"经历了一次彻底的简化:过去由 Node trait、节点槽位与边构成的显式图结构,被普通的 Bevy 调度取代。今天 RenderGraph 只是一个调度标签——渲染世界每帧运行的根调度,所有绘制工作都是挂在这个调度上的系统。
如果你看过 0.18 及更早版本的教程,会见到"渲染图节点"(render graph node)、"输入/输出槽位"这些概念;它们已经不复存在。渲染图现在就是调度,节点就是系统——上一章学的 Schedule 知识在这里原样适用。
RenderGraph 调度
RenderGraph(在 bevy::render::renderer 中)实现 ScheduleLabel。它每帧由渲染世界的 render_system 驱动执行一次,内部预置了四个 SystemSet:
rust
struct CustomNodePlugin;
impl Plugin for CustomNodePlugin {
fn build(&self, app: &mut App) {
let render_app = app.sub_app_mut(RenderApp);
// 在 RenderGraph 调度中注册自定义系统
render_app.add_systems(RenderGraph, custom_node_system);
}
}
fn custom_node_system(mut counter: Local<u32>) {
*counter = counter.wrapping_add(1);
if *counter % 60 == 0 {
info!("自定义节点已运行 {} 帧", *counter);
}
}Listing 37-3:在 RenderGraph 调度中注册自定义系统
| 集合 | 时机 | 用途 |
|---|---|---|
RenderGraphSystems::Begin | 每帧最先 | 逐帧设置,例如更新视图目标 |
RenderGraphSystems::Render | Begin 之后 | 主要渲染阶段 |
RenderGraphSystems::Submit | Render 之后 | 提交 Render 阶段生成的 GPU 命令缓冲 |
RenderGraphSystems::Finish | 最后 | 逐帧收尾,例如截图与 GPU 回读 |
这四个集合按 Begin → Render → Submit → Finish 的顺序链式执行。
节点就是系统
想让自己的逻辑参与渲染,只要在 RenderApp 中往 RenderGraph 调度添加系统即可——与主世界添加系统没有区别:
rust
render_app.add_systems(
RenderGraph,
my_render_system.in_set(RenderGraphSystems::Render),
);系统之间用调度排序 API 表达依赖(第 6 章)。旧版渲染图里"节点 A 的输出连到节点 B 的输入",在 0.19 中就是"系统 A 在系统 B 之前运行"。
渲染世界自己的资源
渲染调度运行在渲染世界中,因此系统只能访问渲染世界的资源与实体。主世界的数据要通过 ExtractSchedule 提取(见 37.2 节),这与旧版没有区别。