渲染调度与阶段集合
渲染子应用有自己的调度体系,和主世界的 Update、PostUpdate 平行运行。
三个调度
| 调度 | 类型 | 何时运行 |
|---|---|---|
RenderStartup | 一次性 | 渲染子应用首次启动时 |
ExtractSchedule | 每帧 | 从主世界提取数据到渲染世界 |
Render | 每帧 | 渲染主流程:准备、排队、排序、绘制、清理 |
ExtractSchedule 特殊——它运行时会临时替换渲染世界的 World,让系统可以同时读取主世界(通过 Extract<T> 或 MainWorld 资源)和写入渲染世界。
Render 调度的阶段集合
Render 调度内部用 RenderSystems(一个 SystemSet)定义了严格的执行顺序。主链是:
ExtractCommands → PrepareMeshes → CreateViews → Specialize → PrepareViews
→ Queue → PhaseSort → Prepare → Render → Cleanup → PostCleanup| 集合 | 职责 |
|---|---|
ExtractCommands | 应用从 ExtractSchedule 累积的命令 |
PrepareAssets | 准备本帧新建/修改/删除的资产(在 ExtractCommands 之后、PrepareMeshes 之前运行) |
PrepareMeshes | 准备 Mesh 数据上传到 GPU |
CreateViews | 创建额外的视图(如阴影贴图的光源视角) |
Specialize | 特化材质网格与阴影视图(按材质参数生成管线变体) |
PrepareViews | 为这些额外视图准备渲染目标与参数 |
Queue | 将可见实体排队为渲染阶段条目(Phase Item) |
QueueMeshes | Queue 的子集,处理 Mesh 排队(依赖 PrepareAssets 完成) |
QueueSweep | Queue 的子集,清理不可见或换阶段的 Mesh |
PhaseSort | 排序渲染阶段(透明物体需要从远到近) |
Prepare | 根据排序结果准备 GPU 资源、创建 BindGroup |
PrepareResources | Prepare 的子集,初始化 Buffer、Texture、Uniform |
PrepareBindGroups | Prepare 的子集,构建 BindGroup(依赖 PrepareResources) |
Render | 实际发出 GPU 绘制命令 |
Cleanup | 清理本帧的临时渲染资源 |
PostCleanup | 销毁标记为 TemporaryRenderEntity 的实体 |
主链已经 chain() 排好了序;Queue 内部按 QueueMeshes → QueueSweep 链式执行,Prepare 内部按 PrepareResources → PrepareResourcesBatchPhases → PrepareResourcesWritePhaseBuffers → PrepareResourcesCollectPhaseBuffers → PrepareResourcesFlush → PrepareBindGroups 链式执行。你注册系统时用 .in_set(RenderSystems::Xxx) 即可精确插入到对应阶段。
完整示例
rust
struct RenderSchedulePlugin;
impl Plugin for RenderSchedulePlugin {
fn build(&self, app: &mut App) {
let render_app = app.sub_app_mut(RenderApp);
// RenderStartup:仅在渲染子应用首次启动时运行一次
render_app.add_systems(RenderStartup, init_render_resources);
// ExtractSchedule:从主世界提取数据到渲染世界
render_app.add_systems(ExtractSchedule, extract_game_state);
// Render 调度:按 RenderSystems 集合的顺序执行
render_app.add_systems(
Render,
(
prepare_my_assets.in_set(RenderSystems::PrepareAssets),
queue_my_draws.in_set(RenderSystems::Queue),
sort_my_phase.in_set(RenderSystems::PhaseSort),
prepare_my_bind_groups.in_set(RenderSystems::Prepare),
issue_draw_calls.in_set(RenderSystems::Render),
cleanup_my_resources.in_set(RenderSystems::Cleanup),
),
);
}
}Listing 37-2:在 Render 调度的各阶段集合中注册系统
RenderStartup
RenderStartup 只运行一次,适合初始化渲染专用的资源——GPU Buffer、管线缓存、BindGroup 布局等。它在第一帧的 ExtractSchedule 之前执行。
时序关系
帧 N:
主世界: Update → PostUpdate → Last
↓ (sync)
渲染世界: ExtractSchedule → Render (各阶段集合依次执行)
帧 N-1 的渲染可能还在 GPU 上执行(流水线并行)Bevy 默认在独立线程上运行渲染,主世界和渲染世界流水线并行——帧 N 的逻辑和帧 N-1 的渲染同时进行。