Fix rendering of sprites, text, and meshlets after #12582. (#12945)

`Sprite`, `Text`, and `Handle<MeshletMesh>` were types of renderable
entities that the new segregated visible entity system didn't handle, so
they didn't appear.

Because `bevy_text` depends on `bevy_sprite`, and the visibility
computation of text happens in the latter crate, I had to introduce a
new marker component, `SpriteSource`. `SpriteSource` marks entities that
aren't themselves sprites but become sprites during rendering. I added
this component to `Text2dBundle`. Unfortunately, this is technically a
breaking change, although I suspect it won't break anybody in practice
except perhaps editors.

Fixes #12935.

## Changelog

### Changed

* `Text2dBundle` now includes a new marker component, `SpriteSource`.
Bevy uses this internally to optimize visibility calculation.

## Migration Guide

* `Text` now requires a `SpriteSource` marker component in order to
appear. This component has been added to `Text2dBundle`.
This commit is contained in:
Patrick Walton 2024-04-13 09:15:00 -05:00 committed by GitHub
parent ae9775c83b
commit 8577a448f7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 75 additions and 13 deletions

View file

@ -56,7 +56,7 @@ use self::{
visibility_buffer_raster_node::MeshletVisibilityBufferRasterPassNode,
};
use crate::{graph::NodePbr, Material};
use bevy_app::{App, Plugin};
use bevy_app::{App, Plugin, PostUpdate};
use bevy_asset::{load_internal_asset, AssetApp, Handle};
use bevy_core_pipeline::{
core_3d::{
@ -68,6 +68,7 @@ use bevy_core_pipeline::{
use bevy_ecs::{
bundle::Bundle,
entity::Entity,
prelude::With,
query::Has,
schedule::IntoSystemConfigs,
system::{Commands, Query},
@ -75,10 +76,14 @@ use bevy_ecs::{
use bevy_render::{
render_graph::{RenderGraphApp, ViewNodeRunner},
render_resource::{Shader, TextureUsages},
view::{prepare_view_targets, InheritedVisibility, Msaa, ViewVisibility, Visibility},
view::{
check_visibility, prepare_view_targets, InheritedVisibility, Msaa, ViewVisibility,
Visibility, VisibilitySystems,
},
ExtractSchedule, Render, RenderApp, RenderSet,
};
use bevy_transform::components::{GlobalTransform, Transform};
use bevy_transform::TransformSystem;
const MESHLET_BINDINGS_SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(1325134235233421);
const MESHLET_MESH_MATERIAL_SHADER_HANDLE: Handle<Shader> =
@ -160,7 +165,18 @@ impl Plugin for MeshletPlugin {
app.init_asset::<MeshletMesh>()
.register_asset_loader(MeshletMeshSaverLoad)
.insert_resource(Msaa::Off);
.insert_resource(Msaa::Off)
.add_systems(
PostUpdate,
check_visibility::<WithMeshletMesh>
.in_set(VisibilitySystems::CheckVisibility)
.after(VisibilitySystems::CalculateBounds)
.after(VisibilitySystems::UpdateOrthographicFrusta)
.after(VisibilitySystems::UpdatePerspectiveFrusta)
.after(VisibilitySystems::UpdateProjectionFrusta)
.after(VisibilitySystems::VisibilityPropagate)
.after(TransformSystem::TransformPropagate),
);
}
fn finish(&self, app: &mut App) {
@ -248,6 +264,10 @@ impl<M: Material> Default for MaterialMeshletMeshBundle<M> {
}
}
/// A convenient alias for `With<Handle<MeshletMesh>>`, for use with
/// [`bevy_render::view::VisibleEntities`].
pub type WithMeshletMesh = With<Handle<MeshletMesh>>;
fn configure_meshlet_views(
mut views_3d: Query<(
Entity,

View file

@ -32,6 +32,7 @@ pub mod prelude {
};
}
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
use bevy_transform::TransformSystem;
pub use bundle::*;
pub use dynamic_texture_atlas_builder::*;
@ -45,8 +46,9 @@ pub use texture_slice::*;
use bevy_app::prelude::*;
use bevy_asset::{load_internal_asset, AssetApp, Assets, Handle};
use bevy_core_pipeline::core_2d::Transparent2d;
use bevy_ecs::prelude::*;
use bevy_ecs::{prelude::*, query::QueryItem};
use bevy_render::{
extract_component::{ExtractComponent, ExtractComponentPlugin},
mesh::Mesh,
primitives::Aabb,
render_phase::AddRenderCommand,
@ -69,6 +71,22 @@ pub enum SpriteSystem {
ComputeSlices,
}
/// A component that marks entities that aren't themselves sprites but become
/// sprites during rendering.
///
/// Right now, this is used for `Text`.
#[derive(Component, Reflect, Clone, Copy, Debug, Default)]
#[reflect(Component, Default)]
pub struct SpriteSource;
/// A convenient alias for `With<Mesh2dHandle>>`, for use with
/// [`bevy_render::view::VisibleEntities`].
pub type WithMesh2d = With<Mesh2dHandle>;
/// A convenient alias for `Or<With<Sprite>, With<SpriteSource>>`, for use with
/// [`bevy_render::view::VisibleEntities`].
pub type WithSprite = Or<(With<Sprite>, With<SpriteSource>)>;
impl Plugin for SpritePlugin {
fn build(&self, app: &mut App) {
load_internal_asset!(
@ -85,7 +103,12 @@ impl Plugin for SpritePlugin {
.register_type::<Anchor>()
.register_type::<TextureAtlas>()
.register_type::<Mesh2dHandle>()
.add_plugins((Mesh2dRenderPlugin, ColorMaterialPlugin))
.register_type::<SpriteSource>()
.add_plugins((
Mesh2dRenderPlugin,
ColorMaterialPlugin,
ExtractComponentPlugin::<SpriteSource>::default(),
))
.add_systems(
PostUpdate,
(
@ -95,7 +118,10 @@ impl Plugin for SpritePlugin {
compute_slices_on_sprite_change,
)
.in_set(SpriteSystem::ComputeSlices),
check_visibility::<WithMesh2d>
(
check_visibility::<WithMesh2d>,
check_visibility::<WithSprite>,
)
.in_set(VisibilitySystems::CheckVisibility)
.after(VisibilitySystems::CalculateBounds)
.after(VisibilitySystems::UpdateOrthographicFrusta)
@ -185,6 +211,18 @@ pub fn calculate_bounds_2d(
}
}
impl ExtractComponent for SpriteSource {
type QueryData = ();
type QueryFilter = ();
type Out = SpriteSource;
fn extract_component(_: QueryItem<'_, Self::QueryData>) -> Option<Self::Out> {
Some(SpriteSource)
}
}
#[cfg(test)]
mod test {

View file

@ -48,10 +48,6 @@ impl From<Handle<Mesh>> for Mesh2dHandle {
}
}
/// A convenient alias for `With<Mesh2dHandle>`, for use with
/// [`bevy_render::view::VisibleEntities`].
pub type WithMesh2d = With<Mesh2dHandle>;
#[derive(Default)]
pub struct Mesh2dRenderPlugin;

View file

@ -2,7 +2,7 @@ use std::ops::Range;
use crate::{
texture_atlas::{TextureAtlas, TextureAtlasLayout},
ComputedTextureSlices, Sprite, WithMesh2d, SPRITE_SHADER_HANDLE,
ComputedTextureSlices, Sprite, WithSprite, SPRITE_SHADER_HANDLE,
};
use bevy_asset::{AssetEvent, AssetId, Assets, Handle};
use bevy_color::LinearRgba;
@ -490,7 +490,7 @@ pub fn queue_sprites(
view_entities.clear();
view_entities.extend(
visible_entities
.iter::<WithMesh2d>()
.iter::<WithSprite>()
.map(|e| e.index() as usize),
);

View file

@ -78,6 +78,10 @@ pub enum YAxisOrientation {
BottomToTop,
}
/// A convenient alias for `With<Text>`, for use with
/// [`bevy_render::view::VisibleEntities`].
pub type WithText = With<Text>;
impl Plugin for TextPlugin {
fn build(&self, app: &mut App) {
app.init_asset::<Font>()

View file

@ -23,7 +23,7 @@ use bevy_render::{
view::{InheritedVisibility, NoFrustumCulling, ViewVisibility, Visibility},
Extract,
};
use bevy_sprite::{Anchor, ExtractedSprite, ExtractedSprites, TextureAtlasLayout};
use bevy_sprite::{Anchor, ExtractedSprite, ExtractedSprites, SpriteSource, TextureAtlasLayout};
use bevy_transform::prelude::{GlobalTransform, Transform};
use bevy_utils::HashSet;
use bevy_window::{PrimaryWindow, Window, WindowScaleFactorChanged};
@ -78,6 +78,10 @@ pub struct Text2dBundle {
pub view_visibility: ViewVisibility,
/// Contains the size of the text and its glyph's position and scale data. Generated via [`TextPipeline::queue_text`]
pub text_layout_info: TextLayoutInfo,
/// Marks that this is a [`SpriteSource`].
///
/// This is needed for visibility computation to work properly.
pub sprite_source: SpriteSource,
}
/// This system extracts the sprites from the 2D text components and adds them to the