Fix(bg motion vectors): gate BackgroundMotionVectorsPlugin pipelines to DownlevelFlags(INDEPENDENT_BLEND) (#24067)

# Objective

- Help out with #23975 
- Fixes an issue on WebGL2 as a result of #23629
- Supporting #23975 on WebGL2 necessitates fixing the “Forward +
Prepass” option on the `deferred_rendering` example. The WebGPU focused
solution to #23629 requires this PR to also allow the “Forward +
Prepass” option to work.

## Solution

- @beicause mentioned gating the whole pipeline of
`background_motion_vectors.rs` to `DownlevelFlags(INDEPENDENT_BLEND)` as
implied in the error message in [this issue
comment](https://github.com/bevyengine/bevy/issues/23975#issuecomment-4362512138).
It works!

## Testing

- Included the change from this PR on top of #24065, and it fixes the
`deferred_rendering` example on WebGL2.
This commit is contained in:
Kevin Chen
2026-05-03 19:55:29 -04:00
committed by GitHub
parent 2730c6ee88
commit ebdd7d983b
@@ -18,16 +18,17 @@ use bevy_ecs::{
schedule::IntoScheduleConfigs,
system::{lifetimeless::Read, Commands, Query, Res, ResMut},
};
use bevy_log::warn;
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
use bevy_render::{
extract_component::{ExtractComponent, ExtractComponentPlugin},
render_resource::{
binding_types::uniform_buffer, BindGroup, BindGroupEntries, BindGroupLayoutDescriptor,
BindGroupLayoutEntries, CachedRenderPipelineId, CompareFunction, DepthStencilState,
FragmentState, MultisampleState, PipelineCache, RenderPipelineDescriptor, ShaderStages,
SpecializedRenderPipeline, SpecializedRenderPipelines,
DownlevelFlags, FragmentState, MultisampleState, PipelineCache, RenderPipelineDescriptor,
ShaderStages, SpecializedRenderPipeline, SpecializedRenderPipelines,
},
renderer::RenderDevice,
renderer::{RenderAdapter, RenderDevice},
sync_component::SyncComponent,
view::{Msaa, ViewUniform, ViewUniforms},
GpuResourceAppExt, Render, RenderApp, RenderStartup, RenderSystems,
@@ -84,19 +85,42 @@ pub struct BackgroundMotionVectorsBindGroup(pub BindGroup);
#[derive(Default)]
pub struct BackgroundMotionVectorsPlugin;
impl BackgroundMotionVectorsPlugin {
/// [`DownlevelFlags`] required for this plugin to function.
pub fn required_downlevel_flags() -> DownlevelFlags {
DownlevelFlags::INDEPENDENT_BLEND
}
}
impl Plugin for BackgroundMotionVectorsPlugin {
fn build(&self, app: &mut App) {
embedded_asset!(app, "background_motion_vectors.wgsl");
app.register_type::<NoBackgroundMotionVectors>()
.add_plugins(ExtractComponentPlugin::<NoBackgroundMotionVectors>::default());
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
return;
};
render_app.init_gpu_resource::<PreviousViewUniforms>();
}
fn finish(&self, app: &mut App) {
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
return;
};
let render_adapter = render_app.world().resource::<RenderAdapter>();
let downlevel_flags = render_adapter.get_downlevel_capabilities().flags;
if !downlevel_flags.contains(BackgroundMotionVectorsPlugin::required_downlevel_flags()) {
warn!(
"BackgroundMotionVectorsPlugin not loaded. GPU lacks support for required downlevel capability flags: {:?}.",
BackgroundMotionVectorsPlugin::required_downlevel_flags().difference(downlevel_flags)
);
return;
}
render_app
.init_gpu_resource::<SpecializedRenderPipelines<BackgroundMotionVectorsPipeline>>()
.init_gpu_resource::<PreviousViewUniforms>()
.add_systems(RenderStartup, init_background_motion_vectors_pipeline)
.add_systems(
Render,