Skip to content

RenderApp:渲染子应用

Bevy 的渲染在独立的子应用(SubApp)中运行,与主 ECS 世界隔离。这个子应用的标签是 RenderApp——一个实现了 AppLabel 的零大小结构体。

双世界架构

主应用(App)负责游戏逻辑、输入、UI 等;渲染子应用负责 GPU 资源管理、绘制命令提交。两者通过 ExtractSchedule 交换数据:每帧从主世界提取组件和资源的快照,复制到渲染世界。

主世界 (Main World)          渲染世界 (Render World)
┌──────────────────┐   Extract   ┌──────────────────┐
│  游戏逻辑系统     │ ─────────→ │  渲染准备系统      │
│  Transform       │            │  PrepareAssets    │
│  Sprite          │            │  Queue            │
│  Camera          │            │  Render           │
└──────────────────┘            └──────────────────┘

访问 RenderApp

Plugin::build 中通过 app.sub_app_mut(RenderApp) 获取渲染子应用的可变引用。拿到之后就可以往里面注册系统、插入资源、配置调度。

rust
struct RenderLogPlugin;

impl Plugin for RenderLogPlugin {
    fn build(&self, app: &mut App) {
        // sub_app_mut 返回 RenderApp 子应用的可变引用
        let render_app = app.sub_app_mut(RenderApp);

        // 在 Render 调度中注册一个系统,放在 RenderSystems::Render 阶段
        render_app.add_systems(Render, log_render_phase.in_set(RenderSystems::Render));
    }
}

fn log_render_phase() {
    info!("Render 阶段正在执行");
}

Listing 37-1:在插件中访问 RenderApp 并注册渲染系统

RenderApp 实现了 DerefMut<Target = SubApp>,所以你可以像操作普通 App 一样调用 add_systemsinsert_resource 等方法。

何时需要访问 RenderApp

大多数游戏不需要直接操作 RenderApp。需要的场景包括:

  • 自定义渲染系统或渲染阶段(往 RenderGraph 调度与 RenderSystems 集合中插入系统)
  • 注册自定义的 ExtractComponentExtractResource
  • 往渲染管线中插入自定义的准备(prepare)或排队(queue)系统
  • 配置 GPU 资源(Buffer、Texture、BindGroup)的生命周期

如果你只是想画东西,高层的 SpriteMesh3dStandardMaterial 已经封装好了一切。