diff --git a/crates/bevy_pbr/src/prepass/mod.rs b/crates/bevy_pbr/src/prepass/mod.rs index 7b70df38aab70..c51d1639f472b 100644 --- a/crates/bevy_pbr/src/prepass/mod.rs +++ b/crates/bevy_pbr/src/prepass/mod.rs @@ -178,7 +178,7 @@ where .add_systems( PreUpdate, ( - update_mesh_previous_global_transforms, + update_mesh_previous_global_transforms.run_if(any_camera_active), update_previous_view_data, ), ) @@ -187,7 +187,12 @@ where BinnedRenderPhasePlugin::::new( self.debug_flags, ), - )); + )) + // This can't be an attribute on the mesh types due to the shape of our dependency graph + .register_required_components::(); + + #[cfg(feature = "meshlet")] + app.register_required_components::(); } let Some(render_app) = app.get_sub_app_mut(RenderApp) else { @@ -257,6 +262,11 @@ pub fn update_previous_view_data( } } +/// Tracks the previous [`GlobalTransform`] of a mesh, +/// assuming that the mesh's transform is affine. +/// +/// This is added as a required component for [`Mesh3d`] and the meshlet equivalent in +/// the [`PrepassPlugin`]. #[derive(Component, PartialEq, Default)] pub struct PreviousGlobalTransform(pub Affine3A); @@ -265,24 +275,18 @@ type PreviousMeshFilter = With; #[cfg(feature = "meshlet")] type PreviousMeshFilter = Or<(With, With)>; +/// A run condition for [`update_mesh_previous_global_transforms`] that checks if any camera is active. +pub fn any_camera_active(views: Query<&Camera, Or<(With, With)>>) -> bool { + views.iter().any(|camera| camera.is_active) +} + +/// Updates the [`PreviousGlobalTransform`] of all meshes that match the [`PreviousMeshFilter`]. pub fn update_mesh_previous_global_transforms( - mut commands: Commands, - views: Query<&Camera, Or<(With, With)>>, - meshes: Query<(Entity, &GlobalTransform, Option<&PreviousGlobalTransform>), PreviousMeshFilter>, + mut meshes: Query<(&GlobalTransform, &mut PreviousGlobalTransform), PreviousMeshFilter>, ) { - let should_run = views.iter().any(|camera| camera.is_active); - - if should_run { - for (entity, transform, old_previous_transform) in &meshes { - let new_previous_transform = PreviousGlobalTransform(transform.affine()); - // Make sure not to trigger change detection on - // `PreviousGlobalTransform` if the previous transform hasn't - // changed. - if old_previous_transform != Some(&new_previous_transform) { - commands.entity(entity).try_insert(new_previous_transform); - } - } - } + meshes.par_iter_mut().for_each(|(transform, mut previous)| { + previous.set_if_neq(PreviousGlobalTransform(transform.affine())); + }); } #[derive(Resource)]