自定义管线搭建
把前面的概念串起来:在渲染子应用中注册系统、分组、建立依赖,构建一个完整的自定义渲染管线。
在 RenderGraph 调度中组织系统
渲染子应用有自己的调度体系,RenderGraph 是其中每帧运行的根调度。往它上面添加系统即可参与渲染:
rust
struct MyGraphPlugin;
impl Plugin for MyGraphPlugin {
fn build(&self, app: &mut App) {
let render_app = app.sub_app_mut(RenderApp);
// 在 RenderGraph 调度中注册系统,使用 .before()/.after() 声明依赖
render_app.add_systems(
RenderGraph,
(node_a, node_b, node_c).chain(), // A → B → C(链式依赖)
);
}
}
fn node_a() {
// 节点 A 的逻辑
}
fn node_b() {
// 节点 B 的逻辑
}
fn node_c() {
// 节点 C 的逻辑
}Listing 37-4:在 RenderGraph 调度中注册系统并声明链式依赖
(node_a, node_b, node_c).chain() 声明 A → B → C 的顺序依赖——旧版渲染图里"画一条边",在 0.19 中就是这个元组调用。
最小自定义管线
下面的示例把所有概念组合在一起:在 RenderStartup 初始化资源、在 ExtractSchedule 提取数据、在 Render 的各阶段执行系统、在 RenderGraph 调度注册自定义标签分组的系统。
rust
struct CustomRenderPlugin;
impl Plugin for CustomRenderPlugin {
fn build(&self, app: &mut App) {
let render_app = app.sub_app_mut(RenderApp);
// 1. 在 RenderStartup 中初始化渲染资源
render_app.add_systems(RenderStartup, init_frame_counter);
// 2. 在 ExtractSchedule 中提取主世界数据
render_app.add_systems(ExtractSchedule, extract_time);
// 3. 在 Render 调度的各阶段注册系统
render_app.add_systems(
Render,
prepare_counter
.in_set(RenderSystems::Prepare)
.before(RenderSystems::Render),
);
// 4. 在 RenderGraph 调度中注册系统,并用自定义标签分组
render_app.add_systems(
RenderGraph,
log_frame_in_graph.in_set(CustomRenderLabels::FrameLog),
);
}
}rust
/// 自定义渲染标签:0.19 中渲染图标签就是 SystemSet
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
enum CustomRenderLabels {
/// 帧日志系统
FrameLog,
}rust
#[derive(Resource, Default)]
struct FrameCounter {
frames: u64,
}
fn init_frame_counter(mut commands: Commands) {
commands.insert_resource(FrameCounter::default());
}
fn extract_time(mut counter: ResMut<FrameCounter>) {
counter.frames += 1;
if counter.frames % 300 == 0 {
info!("渲染管线已运行 {} 帧", counter.frames);
}
}
fn prepare_counter(counter: Res<FrameCounter>) {
let _ = counter.frames;
}rust
fn log_frame_in_graph(mut counter: ResMut<FrameCounter>) {
counter.frames = counter.frames.wrapping_add(1);
}Listing 37-5:最小自定义渲染管线——插件、标签、资源与节点
标签是 SystemSet(第 6 章的集合机制,渲染世界同样适用)。CustomRenderLabels::FrameLog 把帧日志系统归组,方便统一排序。
运行方式
console
cargo run -p ch37-render-arch每 300 帧会输出一条日志,表明自定义渲染管线在正常运行。