mirror of
https://github.com/bevyengine/bevy
synced 2025-02-16 14:08:32 +00:00
Add Aabb
calculation for Sprite
, TextureAtlasSprite
and Mesh2d
(#7885)
# Objective - Add `Aabb` calculation for `Sprite`, `TextureAtlasSprite` and `Mesh2d`. - Enable frustum culling for 2D entities since frustum culling requires a `Aabb` component in the entity to function. - Improve 2D performance massively when there are many sprites out of view. (ex: `many_sprites`) ## Solution - Derived from @Weasy666's #3944 pull request, which had no activity since multiple months. - Adapted the code to the latest version of Bevy. - Added support for sprites with non-center `Anchor`s to avoid culling prematurely when part of the sprite is still in view or not culling when sprite is already out of view. ### Note - Gives 15.8x performance boosts in some scenarios. (5 fps vs 79 fps with 409600 sprites in `many_sprites`) --------- Co-authored-by: ira <JustTheCoolDude@gmail.com>
This commit is contained in:
parent
bb37ae4ab3
commit
9a3225d3a8
1 changed files with 60 additions and 2 deletions
|
@ -29,13 +29,17 @@ pub use texture_atlas::*;
|
|||
pub use texture_atlas_builder::*;
|
||||
|
||||
use bevy_app::prelude::*;
|
||||
use bevy_asset::{AddAsset, Assets, HandleUntyped};
|
||||
use bevy_asset::{AddAsset, Assets, Handle, HandleUntyped};
|
||||
use bevy_core_pipeline::core_2d::Transparent2d;
|
||||
use bevy_ecs::prelude::*;
|
||||
use bevy_reflect::TypeUuid;
|
||||
use bevy_render::{
|
||||
mesh::Mesh,
|
||||
primitives::Aabb,
|
||||
render_phase::AddRenderCommand,
|
||||
render_resource::{Shader, SpecializedRenderPipelines},
|
||||
texture::Image,
|
||||
view::{NoFrustumCulling, VisibilitySystems},
|
||||
ExtractSchedule, Render, RenderApp, RenderSet,
|
||||
};
|
||||
|
||||
|
@ -62,7 +66,11 @@ impl Plugin for SpritePlugin {
|
|||
.register_type::<Anchor>()
|
||||
.register_type::<Mesh2dHandle>()
|
||||
.add_plugin(Mesh2dRenderPlugin)
|
||||
.add_plugin(ColorMaterialPlugin);
|
||||
.add_plugin(ColorMaterialPlugin)
|
||||
.add_systems(
|
||||
PostUpdate,
|
||||
calculate_bounds_2d.in_set(VisibilitySystems::CalculateBounds),
|
||||
);
|
||||
|
||||
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
|
||||
render_app
|
||||
|
@ -89,3 +97,53 @@ impl Plugin for SpritePlugin {
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn calculate_bounds_2d(
|
||||
mut commands: Commands,
|
||||
meshes: Res<Assets<Mesh>>,
|
||||
images: Res<Assets<Image>>,
|
||||
atlases: Res<Assets<TextureAtlas>>,
|
||||
meshes_without_aabb: Query<(Entity, &Mesh2dHandle), (Without<Aabb>, Without<NoFrustumCulling>)>,
|
||||
sprites_without_aabb: Query<
|
||||
(Entity, &Sprite, &Handle<Image>),
|
||||
(Without<Aabb>, Without<NoFrustumCulling>),
|
||||
>,
|
||||
atlases_without_aabb: Query<
|
||||
(Entity, &TextureAtlasSprite, &Handle<TextureAtlas>),
|
||||
(Without<Aabb>, Without<NoFrustumCulling>),
|
||||
>,
|
||||
) {
|
||||
for (entity, mesh_handle) in &meshes_without_aabb {
|
||||
if let Some(mesh) = meshes.get(&mesh_handle.0) {
|
||||
if let Some(aabb) = mesh.compute_aabb() {
|
||||
commands.entity(entity).insert(aabb);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (entity, sprite, texture_handle) in &sprites_without_aabb {
|
||||
if let Some(size) = sprite
|
||||
.custom_size
|
||||
.or_else(|| images.get(texture_handle).map(|image| image.size()))
|
||||
{
|
||||
let aabb = Aabb {
|
||||
center: (-sprite.anchor.as_vec() * size).extend(0.0).into(),
|
||||
half_extents: (0.5 * size).extend(0.0).into(),
|
||||
};
|
||||
commands.entity(entity).insert(aabb);
|
||||
}
|
||||
}
|
||||
for (entity, atlas_sprite, atlas_handle) in &atlases_without_aabb {
|
||||
if let Some(size) = atlas_sprite.custom_size.or_else(|| {
|
||||
atlases
|
||||
.get(atlas_handle)
|
||||
.and_then(|atlas| atlas.textures.get(atlas_sprite.index))
|
||||
.map(|rect| (rect.min - rect.max).abs())
|
||||
}) {
|
||||
let aabb = Aabb {
|
||||
center: (-atlas_sprite.anchor.as_vec() * size).extend(0.0).into(),
|
||||
half_extents: (0.5 * size).extend(0.0).into(),
|
||||
};
|
||||
commands.entity(entity).insert(aabb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue