diff --git a/crates/bevy_pbr/src/bundle.rs b/crates/bevy_pbr/src/bundle.rs index f7fb757c6b349..8e0543ff03dad 100644 --- a/crates/bevy_pbr/src/bundle.rs +++ b/crates/bevy_pbr/src/bundle.rs @@ -5,7 +5,7 @@ use bevy_reflect::Reflect; use bevy_render::{ mesh::Mesh, primitives::{CubemapFrusta, Frustum}, - view::{ComputedVisibility, Visible, VisibleEntities}, + view::{Visible, VisibleEntities}, }; use bevy_transform::components::{GlobalTransform, Transform}; @@ -21,8 +21,6 @@ pub struct MaterialMeshBundle { pub global_transform: GlobalTransform, /// User indication of whether an entity is visible pub visible: Visible, - /// Algorithmically-computed indication of whether an entity is visible and should be extracted for rendering - pub computed_visibility: ComputedVisibility, } impl Default for MaterialMeshBundle { @@ -33,7 +31,6 @@ impl Default for MaterialMeshBundle { transform: Default::default(), global_transform: Default::default(), visible: Default::default(), - computed_visibility: Default::default(), } } } diff --git a/crates/bevy_pbr/src/lib.rs b/crates/bevy_pbr/src/lib.rs index 180093f9ba50a..887de0185db12 100644 --- a/crates/bevy_pbr/src/lib.rs +++ b/crates/bevy_pbr/src/lib.rs @@ -119,11 +119,7 @@ impl Plugin for PbrPlugin { .after(TransformSystem::TransformPropagate) .after(VisibilitySystems::CalculateBounds) .after(SimulationLightSystems::UpdateDirectionalLightFrusta) - .after(SimulationLightSystems::UpdatePointLightFrusta) - // NOTE: This MUST be scheduled AFTER the core renderer visibility check - // because that resets entity ComputedVisibility for the first view - // which would override any results from this otherwise - .after(VisibilitySystems::CheckVisibility), + .after(SimulationLightSystems::UpdatePointLightFrusta), ); app.world diff --git a/crates/bevy_pbr/src/light.rs b/crates/bevy_pbr/src/light.rs index 9bab5702c4921..c09c0ec04afed 100644 --- a/crates/bevy_pbr/src/light.rs +++ b/crates/bevy_pbr/src/light.rs @@ -7,7 +7,7 @@ use bevy_render::{ camera::{Camera, CameraProjection, OrthographicProjection}, color::Color, primitives::{Aabb, CubemapFrusta, Frustum, Sphere}, - view::{ComputedVisibility, RenderLayers, Visible, VisibleEntities}, + view::{RenderLayers, Visible, VisibleEntities}, }; use bevy_transform::components::GlobalTransform; use bevy_window::Windows; @@ -702,10 +702,9 @@ pub fn check_light_mesh_visibility( &mut VisibleEntities, Option<&RenderLayers>, )>, - mut visible_entity_query: Query< + visible_entity_query: Query< ( Entity, - &mut ComputedVisibility, Option<&RenderLayers>, Option<&Aabb>, Option<&GlobalTransform>, @@ -713,7 +712,7 @@ pub fn check_light_mesh_visibility( (Without, With), >, ) { - // Directonal lights + // Directional lights for (directional_light, frustum, mut visible_entities, maybe_view_mask) in directional_lights.iter_mut() { @@ -726,8 +725,7 @@ pub fn check_light_mesh_visibility( let view_mask = maybe_view_mask.copied().unwrap_or_default(); - for (entity, mut computed_visibility, maybe_entity_mask, maybe_aabb, maybe_transform) in - visible_entity_query.iter_mut() + for (entity, maybe_entity_mask, maybe_aabb, maybe_transform) in visible_entity_query.iter() { let entity_mask = maybe_entity_mask.copied().unwrap_or_default(); if !view_mask.intersects(&entity_mask) { @@ -740,8 +738,6 @@ pub fn check_light_mesh_visibility( continue; } } - - computed_visibility.is_visible = true; visible_entities.entities.push(entity); } @@ -775,13 +771,8 @@ pub fn check_light_mesh_visibility( radius: point_light.range, }; - for ( - entity, - mut computed_visibility, - maybe_entity_mask, - maybe_aabb, - maybe_transform, - ) in visible_entity_query.iter_mut() + for (entity, maybe_entity_mask, maybe_aabb, maybe_transform) in + visible_entity_query.iter() { let entity_mask = maybe_entity_mask.copied().unwrap_or_default(); if !view_mask.intersects(&entity_mask) { @@ -800,12 +791,10 @@ pub fn check_light_mesh_visibility( .zip(cubemap_visible_entities.iter_mut()) { if frustum.intersects_obb(aabb, &model_to_world) { - computed_visibility.is_visible = true; visible_entities.entities.push(entity); } } } else { - computed_visibility.is_visible = true; for visible_entities in cubemap_visible_entities.iter_mut() { visible_entities.entities.push(entity) } diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index 3e8965aa28ee1..b970cafb51e86 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -10,6 +10,7 @@ use bevy_ecs::{ }; use bevy_math::{Mat4, Size}; use bevy_reflect::TypeUuid; +use bevy_render::view::{Visible, VisibleEntities}; use bevy_render::{ mesh::{GpuBufferInfo, Mesh}, render_asset::RenderAssets, @@ -18,10 +19,11 @@ use bevy_render::{ render_resource::{std140::AsStd140, *}, renderer::{RenderDevice, RenderQueue}, texture::{BevyDefault, GpuImage, Image, TextureFormatPixelInfo}, - view::{ComputedVisibility, ViewUniform, ViewUniformOffset, ViewUniforms}, + view::{ViewUniform, ViewUniformOffset, ViewUniforms}, RenderApp, RenderStage, }; use bevy_transform::components::GlobalTransform; +use bevy_utils::HashSet; #[derive(Default)] pub struct MeshRenderPlugin; @@ -84,30 +86,33 @@ pub fn extract_meshes( mut commands: Commands, mut previous_caster_len: Local, mut previous_not_caster_len: Local, + visible_entities_query: Query<&VisibleEntities>, caster_query: Query< ( Entity, - &ComputedVisibility, &GlobalTransform, &Handle, Option<&NotShadowReceiver>, ), - Without, + (Without, With), >, not_caster_query: Query< ( Entity, - &ComputedVisibility, &GlobalTransform, &Handle, Option<&NotShadowReceiver>, ), - With, + (With, With), >, ) { + let visible_entities: HashSet = visible_entities_query + .iter() + .flat_map(|v| v.entities.clone()) + .collect(); let mut caster_values = Vec::with_capacity(*previous_caster_len); - for (entity, computed_visibility, transform, handle, not_receiver) in caster_query.iter() { - if !computed_visibility.is_visible { + for (entity, transform, handle, not_receiver) in caster_query.iter() { + if !visible_entities.contains(&entity) { continue; } let transform = transform.compute_matrix(); @@ -131,8 +136,8 @@ pub fn extract_meshes( commands.insert_or_spawn_batch(caster_values); let mut not_caster_values = Vec::with_capacity(*previous_not_caster_len); - for (entity, computed_visibility, transform, handle, not_receiver) in not_caster_query.iter() { - if !computed_visibility.is_visible { + for (entity, transform, handle, not_receiver) in not_caster_query.iter() { + if !visible_entities.contains(&entity) { continue; } let transform = transform.compute_matrix(); diff --git a/crates/bevy_render/src/camera/mod.rs b/crates/bevy_render/src/camera/mod.rs index 33d54bd5057c8..d80cc516bcd31 100644 --- a/crates/bevy_render/src/camera/mod.rs +++ b/crates/bevy_render/src/camera/mod.rs @@ -14,7 +14,7 @@ pub use projection::*; use crate::{ primitives::Aabb, - view::{ComputedVisibility, ExtractedView, Visible, VisibleEntities}, + view::{ExtractedView, Visible, VisibleEntities}, RenderApp, RenderStage, }; use bevy_app::{App, CoreStage, Plugin}; @@ -35,7 +35,6 @@ impl Plugin for CameraPlugin { active_cameras.add(Self::CAMERA_3D); app.register_type::() .register_type::() - .register_type::() .register_type::() .register_type::() .register_type::() diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index 14c72a0dabeb3..1068ebea8ed04 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -23,7 +23,7 @@ pub mod prelude { mesh::{shape, Mesh}, render_resource::Shader, texture::Image, - view::{ComputedVisibility, Msaa, Visible}, + view::{Msaa, Visible}, }; } diff --git a/crates/bevy_render/src/view/visibility/mod.rs b/crates/bevy_render/src/view/visibility/mod.rs index 9e7a7506e2997..d5cea9be7832a 100644 --- a/crates/bevy_render/src/view/visibility/mod.rs +++ b/crates/bevy_render/src/view/visibility/mod.rs @@ -19,19 +19,6 @@ use crate::{ #[reflect(Component)] pub struct Visible; -/// Algorithmically-computed indication of whether an entity is visible and should be extracted for rendering -#[derive(Component, Clone, Reflect, Debug)] -#[reflect(Component)] -pub struct ComputedVisibility { - pub is_visible: bool, -} - -impl Default for ComputedVisibility { - fn default() -> Self { - Self { is_visible: true } - } -} - /// Use this component to opt-out of built-in frustum culling for Mesh entities #[derive(Component)] pub struct NoFrustumCulling; @@ -130,38 +117,23 @@ pub fn update_frusta( pub fn check_visibility( mut view_query: Query<(&mut VisibleEntities, &Frustum, Option<&RenderLayers>), With>, - mut visible_entity_query: QuerySet<( - QueryState<&mut ComputedVisibility>, - QueryState< - ( - Entity, - &mut ComputedVisibility, - Option<&RenderLayers>, - Option<&Aabb>, - Option<&NoFrustumCulling>, - Option<&GlobalTransform>, - ), - With, - >, - )>, + visible_entity_query: Query< + ( + Entity, + Option<&RenderLayers>, + Option<&Aabb>, + Option<&NoFrustumCulling>, + Option<&GlobalTransform>, + ), + With, + >, ) { - // Reset the computed visibility to false - for mut computed_visibility in visible_entity_query.q0().iter_mut() { - computed_visibility.is_visible = false; - } - for (mut visible_entities, frustum, maybe_view_mask) in view_query.iter_mut() { visible_entities.entities.clear(); let view_mask = maybe_view_mask.copied().unwrap_or_default(); - for ( - entity, - mut computed_visibility, - maybe_entity_mask, - maybe_aabb, - maybe_no_frustum_culling, - maybe_transform, - ) in visible_entity_query.q1().iter_mut() + for (entity, maybe_entity_mask, maybe_aabb, maybe_no_frustum_culling, maybe_transform) in + visible_entity_query.iter() { let entity_mask = maybe_entity_mask.copied().unwrap_or_default(); if !view_mask.intersects(&entity_mask) { @@ -176,8 +148,6 @@ pub fn check_visibility( continue; } } - - computed_visibility.is_visible = true; visible_entities.entities.push(entity); } diff --git a/crates/bevy_sprite/src/mesh2d/material.rs b/crates/bevy_sprite/src/mesh2d/material.rs index edba76249ea41..cc4dc2b2276d2 100644 --- a/crates/bevy_sprite/src/mesh2d/material.rs +++ b/crates/bevy_sprite/src/mesh2d/material.rs @@ -24,7 +24,7 @@ use bevy_render::{ SpecializedPipeline, SpecializedPipelines, }, renderer::RenderDevice, - view::{ComputedVisibility, Msaa, Visible, VisibleEntities}, + view::{Msaa, Visible, VisibleEntities}, RenderApp, RenderStage, }; use bevy_transform::components::{GlobalTransform, Transform}; @@ -327,8 +327,6 @@ pub struct MaterialMesh2dBundle { pub global_transform: GlobalTransform, /// User indication of whether an entity is visible pub visible: Visible, - /// Algorithmically-computed indication of whether an entity is visible and should be extracted for rendering - pub computed_visibility: ComputedVisibility, } impl Default for MaterialMesh2dBundle { @@ -339,7 +337,6 @@ impl Default for MaterialMesh2dBundle { transform: Default::default(), global_transform: Default::default(), visible: Default::default(), - computed_visibility: Default::default(), } } } diff --git a/crates/bevy_sprite/src/mesh2d/mesh.rs b/crates/bevy_sprite/src/mesh2d/mesh.rs index 7468990b47ea8..c535ec66708db 100644 --- a/crates/bevy_sprite/src/mesh2d/mesh.rs +++ b/crates/bevy_sprite/src/mesh2d/mesh.rs @@ -6,6 +6,7 @@ use bevy_ecs::{ }; use bevy_math::{Mat4, Size}; use bevy_reflect::TypeUuid; +use bevy_render::view::{Visible, VisibleEntities}; use bevy_render::{ mesh::{GpuBufferInfo, Mesh}, render_asset::RenderAssets, @@ -14,10 +15,11 @@ use bevy_render::{ render_resource::{std140::AsStd140, *}, renderer::{RenderDevice, RenderQueue}, texture::{BevyDefault, GpuImage, Image, TextureFormatPixelInfo}, - view::{ComputedVisibility, ExtractedView, ViewUniform, ViewUniformOffset, ViewUniforms}, + view::{ExtractedView, ViewUniform, ViewUniformOffset, ViewUniforms}, RenderApp, RenderStage, }; use bevy_transform::components::GlobalTransform; +use bevy_utils::HashSet; /// Component for rendering with meshes in the 2d pipeline, usually with a [2d material](crate::Material2d) such as [`ColorMaterial`](crate::ColorMaterial). /// @@ -91,11 +93,16 @@ bitflags::bitflags! { pub fn extract_mesh2d( mut commands: Commands, mut previous_len: Local, - query: Query<(Entity, &ComputedVisibility, &GlobalTransform, &Mesh2dHandle)>, + visible_entities_query: Query<&VisibleEntities>, + query: Query<(Entity, &GlobalTransform, &Mesh2dHandle), With>, ) { + let visible_entities: HashSet = visible_entities_query + .iter() + .flat_map(|v| v.entities.clone()) + .collect(); let mut values = Vec::with_capacity(*previous_len); - for (entity, computed_visibility, transform, handle) in query.iter() { - if !computed_visibility.is_visible { + for (entity, transform, handle) in query.iter() { + if !visible_entities.contains(&entity) { continue; } let transform = transform.compute_matrix();