From 1c695c9ca48c9a05ccf641563023dc3bfc78d7ea Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 12 Apr 2024 12:58:50 -0700 Subject: [PATCH] Fix rendering of sprites, text, and meshlets after #12582. `Sprite`, `Text`, and `Handle` 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. --- crates/bevy_pbr/src/meshlet/mod.rs | 26 ++++++++++++++-- crates/bevy_sprite/src/lib.rs | 44 +++++++++++++++++++++++++-- crates/bevy_sprite/src/mesh2d/mesh.rs | 4 --- crates/bevy_sprite/src/render/mod.rs | 4 +-- crates/bevy_text/src/lib.rs | 15 ++++++++- crates/bevy_text/src/text2d.rs | 6 +++- 6 files changed, 85 insertions(+), 14 deletions(-) diff --git a/crates/bevy_pbr/src/meshlet/mod.rs b/crates/bevy_pbr/src/meshlet/mod.rs index 3770675a9a149..327b9b3077192 100644 --- a/crates/bevy_pbr/src/meshlet/mod.rs +++ b/crates/bevy_pbr/src/meshlet/mod.rs @@ -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 = Handle::weak_from_u128(1325134235233421); const MESHLET_MESH_MATERIAL_SHADER_HANDLE: Handle = @@ -160,7 +165,18 @@ impl Plugin for MeshletPlugin { app.init_asset::() .register_asset_loader(MeshletMeshSaverLoad) - .insert_resource(Msaa::Off); + .insert_resource(Msaa::Off) + .add_systems( + PostUpdate, + check_visibility:: + .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 Default for MaterialMeshletMeshBundle { } } +/// A convenient alias for `With>`, for use with +/// [`VisibleEntities`]. +pub type WithMeshletMesh = With>; + fn configure_meshlet_views( mut views_3d: Query<( Entity, diff --git a/crates/bevy_sprite/src/lib.rs b/crates/bevy_sprite/src/lib.rs index 42b715e07a49e..9b7740570c875 100644 --- a/crates/bevy_sprite/src/lib.rs +++ b/crates/bevy_sprite/src/lib.rs @@ -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>`, for use with +/// [`bevy_render::view::VisibleEntities`]. +pub type WithMesh2d = With; + +/// A convenient alias for `Or, With>`, for use with +/// [`bevy_render::view::VisibleEntities`]. +pub type WithSprite = Or<(With, With)>; + impl Plugin for SpritePlugin { fn build(&self, app: &mut App) { load_internal_asset!( @@ -85,7 +103,12 @@ impl Plugin for SpritePlugin { .register_type::() .register_type::() .register_type::() - .add_plugins((Mesh2dRenderPlugin, ColorMaterialPlugin)) + .register_type::() + .add_plugins(( + Mesh2dRenderPlugin, + ColorMaterialPlugin, + ExtractComponentPlugin::::default(), + )) .add_systems( PostUpdate, ( @@ -95,7 +118,10 @@ impl Plugin for SpritePlugin { compute_slices_on_sprite_change, ) .in_set(SpriteSystem::ComputeSlices), - check_visibility:: + ( + check_visibility::, + check_visibility::, + ) .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 { + Some(SpriteSource) + } +} + #[cfg(test)] mod test { diff --git a/crates/bevy_sprite/src/mesh2d/mesh.rs b/crates/bevy_sprite/src/mesh2d/mesh.rs index 21d4fe4fc5710..257ad61dfbb7f 100644 --- a/crates/bevy_sprite/src/mesh2d/mesh.rs +++ b/crates/bevy_sprite/src/mesh2d/mesh.rs @@ -48,10 +48,6 @@ impl From> for Mesh2dHandle { } } -/// A convenient alias for `With`, for use with -/// [`bevy_render::view::VisibleEntities`]. -pub type WithMesh2d = With; - #[derive(Default)] pub struct Mesh2dRenderPlugin; diff --git a/crates/bevy_sprite/src/render/mod.rs b/crates/bevy_sprite/src/render/mod.rs index 8df063e93b5ff..ccf29c63577ca 100644 --- a/crates/bevy_sprite/src/render/mod.rs +++ b/crates/bevy_sprite/src/render/mod.rs @@ -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::() + .iter::() .map(|e| e.index() as usize), ); diff --git a/crates/bevy_text/src/lib.rs b/crates/bevy_text/src/lib.rs index 014f56818ba7b..d013831d0d644 100644 --- a/crates/bevy_text/src/lib.rs +++ b/crates/bevy_text/src/lib.rs @@ -38,7 +38,9 @@ use bevy_asset::AssetApp; use bevy_asset::{load_internal_binary_asset, Handle}; use bevy_ecs::prelude::*; use bevy_render::{ - camera::CameraUpdateSystem, view::VisibilitySystems, ExtractSchedule, RenderApp, + camera::CameraUpdateSystem, + view::{check_visibility, VisibilitySystems}, + ExtractSchedule, RenderApp, }; use bevy_sprite::SpriteSystem; use std::num::NonZeroUsize; @@ -78,6 +80,10 @@ pub enum YAxisOrientation { BottomToTop, } +/// A convenient alias for `With`, for use with +/// [`bevy_render::view::VisibleEntities`]. +pub type WithText = With; + impl Plugin for TextPlugin { fn build(&self, app: &mut App) { app.init_asset::() @@ -101,6 +107,13 @@ impl Plugin for TextPlugin { // will never modify a pre-existing `Image` asset. .ambiguous_with(CameraUpdateSystem), remove_dropped_font_atlas_sets, + check_visibility:: + .in_set(VisibilitySystems::CheckVisibility) + .after(VisibilitySystems::CalculateBounds) + .after(VisibilitySystems::UpdateOrthographicFrusta) + .after(VisibilitySystems::UpdatePerspectiveFrusta) + .after(VisibilitySystems::UpdateProjectionFrusta) + .after(VisibilitySystems::VisibilityPropagate), ), ); diff --git a/crates/bevy_text/src/text2d.rs b/crates/bevy_text/src/text2d.rs index 5212e39e2a86d..cf99ec72e459d 100644 --- a/crates/bevy_text/src/text2d.rs +++ b/crates/bevy_text/src/text2d.rs @@ -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