Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions crates/bevy_pbr/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ use crate::{
StandardMaterial,
};
use bevy_asset::Handle;
use bevy_ecs::entity::EntityHashMap;
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::entity::{Entity, EntityHashMap};
use bevy_ecs::{bundle::Bundle, component::Component, reflect::ReflectComponent};
use bevy_reflect::Reflect;
use bevy_render::{
mesh::Mesh,
primitives::{CascadesFrusta, CubemapFrusta, Frustum},
view::{InheritedVisibility, ViewVisibility, Visibility, VisibleEntities},
view::{InheritedVisibility, ViewVisibility, Visibility},
};
use bevy_transform::components::{GlobalTransform, Transform};

Expand Down Expand Up @@ -45,27 +46,37 @@ impl<M: Material> Default for MaterialMeshBundle<M> {
}
}

/// Collection of mesh entities visible for 3D lighting.
/// This component contains all mesh entities visible from the current light view.
/// The collection is updated automatically by [`crate::SimulationLightSystems`].
#[derive(Component, Clone, Debug, Default, Reflect, Deref, DerefMut)]
#[reflect(Component)]
pub struct VisibleMeshEntities {
#[reflect(ignore)]
pub entities: Vec<Entity>,
}

#[derive(Component, Clone, Debug, Default, Reflect)]
#[reflect(Component)]
pub struct CubemapVisibleEntities {
#[reflect(ignore)]
data: [VisibleEntities; 6],
data: [VisibleMeshEntities; 6],
}

impl CubemapVisibleEntities {
pub fn get(&self, i: usize) -> &VisibleEntities {
pub fn get(&self, i: usize) -> &VisibleMeshEntities {
&self.data[i]
}

pub fn get_mut(&mut self, i: usize) -> &mut VisibleEntities {
pub fn get_mut(&mut self, i: usize) -> &mut VisibleMeshEntities {
&mut self.data[i]
}

pub fn iter(&self) -> impl DoubleEndedIterator<Item = &VisibleEntities> {
pub fn iter(&self) -> impl DoubleEndedIterator<Item = &VisibleMeshEntities> {
self.data.iter()
}

pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut VisibleEntities> {
pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut VisibleMeshEntities> {
self.data.iter_mut()
}
}
Expand All @@ -75,7 +86,7 @@ impl CubemapVisibleEntities {
pub struct CascadesVisibleEntities {
/// Map of view entity to the visible entities for each cascade frustum.
#[reflect(ignore)]
pub entities: EntityHashMap<Vec<VisibleEntities>>,
pub entities: EntityHashMap<Vec<VisibleMeshEntities>>,
}

/// A component bundle for [`PointLight`] entities.
Expand All @@ -98,7 +109,7 @@ pub struct PointLightBundle {
#[derive(Debug, Bundle, Default, Clone)]
pub struct SpotLightBundle {
pub spot_light: SpotLight,
pub visible_entities: VisibleEntities,
pub visible_entities: VisibleMeshEntities,
pub frustum: Frustum,
pub transform: Transform,
pub global_transform: GlobalTransform,
Expand Down
29 changes: 12 additions & 17 deletions crates/bevy_pbr/src/light/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ use bevy_render::{
mesh::Mesh,
primitives::{Aabb, CascadesFrusta, CubemapFrusta, Frustum, Sphere},
view::{
InheritedVisibility, RenderLayers, ViewVisibility, VisibilityRange, VisibleEntities,
VisibleEntityRanges, WithMesh,
InheritedVisibility, RenderLayers, ViewVisibility, VisibilityRange, VisibleEntityRanges,
},
};
use bevy_transform::components::{GlobalTransform, Transform};
Expand Down Expand Up @@ -100,7 +99,7 @@ impl Default for PointLightShadowMap {
}

/// A convenient alias for `Or<(With<PointLight>, With<SpotLight>,
/// With<DirectionalLight>)>`, for use with [`VisibleEntities`].
/// With<DirectionalLight>)>`, for use with [`bevy_render::view::VisibleEntities`].
pub type WithLight = Or<(With<PointLight>, With<SpotLight>, With<DirectionalLight>)>;

/// Controls the resolution of [`DirectionalLight`] shadow maps.
Expand Down Expand Up @@ -698,9 +697,7 @@ pub fn check_dir_light_mesh_visibility(
match frusta.frusta.get(view) {
Some(view_frusta) => {
cascade_view_entities.resize(view_frusta.len(), Default::default());
cascade_view_entities
.iter_mut()
.for_each(VisibleEntities::clear::<WithMesh>);
cascade_view_entities.iter_mut().for_each(|x| x.clear());
}
None => views_to_remove.push(*view),
};
Expand All @@ -709,7 +706,7 @@ pub fn check_dir_light_mesh_visibility(
visible_entities
.entities
.entry(*view)
.or_insert_with(|| vec![VisibleEntities::default(); frusta.len()]);
.or_insert_with(|| vec![VisibleMeshEntities::default(); frusta.len()]);
}

for v in views_to_remove {
Expand Down Expand Up @@ -790,7 +787,6 @@ pub fn check_dir_light_mesh_visibility(
.get_mut(view)
.unwrap()
.iter_mut()
.map(VisibleEntities::get_mut::<WithMesh>)
.zip(entities.iter_mut())
.for_each(|(dst, source)| {
dst.append(source);
Expand All @@ -801,7 +797,7 @@ pub fn check_dir_light_mesh_visibility(
for (_, cascade_view_entities) in &mut visible_entities.entities {
cascade_view_entities
.iter_mut()
.map(VisibleEntities::get_mut::<WithMesh>)
.map(DerefMut::deref_mut)
.for_each(shrink_entities);
}
}
Expand Down Expand Up @@ -833,7 +829,7 @@ pub fn check_point_light_mesh_visibility(
&SpotLight,
&GlobalTransform,
&Frustum,
&mut VisibleEntities,
&mut VisibleMeshEntities,
Option<&RenderLayers>,
)>,
mut visible_entity_query: Query<
Expand Down Expand Up @@ -869,7 +865,7 @@ pub fn check_point_light_mesh_visibility(
)) = point_lights.get_mut(light_entity)
{
for visible_entities in cubemap_visible_entities.iter_mut() {
visible_entities.clear::<WithMesh>();
visible_entities.entities.clear();
}

// NOTE: If shadow mapping is disabled for the light then it must have no visible entities
Expand Down Expand Up @@ -940,21 +936,20 @@ pub fn check_point_light_mesh_visibility(
for entities in cubemap_visible_entities_queue.iter_mut() {
cubemap_visible_entities
.iter_mut()
.map(VisibleEntities::get_mut::<WithMesh>)
.zip(entities.iter_mut())
.for_each(|(dst, source)| dst.append(source));
.for_each(|(dst, source)| dst.entities.append(source));
}

for visible_entities in cubemap_visible_entities.iter_mut() {
shrink_entities(visible_entities.get_mut::<WithMesh>());
shrink_entities(visible_entities);
}
}

// Spot lights
if let Ok((point_light, transform, frustum, mut visible_entities, maybe_view_mask)) =
spot_lights.get_mut(light_entity)
{
visible_entities.clear::<WithMesh>();
visible_entities.clear();

// NOTE: If shadow mapping is disabled for the light then it must have no visible entities
if !point_light.shadows_enabled {
Expand Down Expand Up @@ -1015,10 +1010,10 @@ pub fn check_point_light_mesh_visibility(
);

for entities in spot_visible_entities_queue.iter_mut() {
visible_entities.get_mut::<WithMesh>().append(entities);
visible_entities.append(entities);
}

shrink_entities(visible_entities.get_mut::<WithMesh>());
shrink_entities(visible_entities.deref_mut());
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions crates/bevy_pbr/src/render/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use bevy_render::{
render_resource::*,
renderer::{RenderContext, RenderDevice, RenderQueue},
texture::*,
view::{ExtractedView, RenderLayers, ViewVisibility, VisibleEntities, WithMesh},
view::{ExtractedView, RenderLayers, ViewVisibility},
Extract,
};
use bevy_transform::{components::GlobalTransform, prelude::Transform};
Expand Down Expand Up @@ -186,7 +186,7 @@ pub fn extract_lights(
spot_lights: Extract<
Query<(
&SpotLight,
&VisibleEntities,
&VisibleMeshEntities,
&GlobalTransform,
&ViewVisibility,
&Frustum,
Expand Down Expand Up @@ -1174,7 +1174,7 @@ pub fn queue_shadows<M: Material>(
mut view_light_entities: Query<&LightEntity>,
point_light_entities: Query<&CubemapVisibleEntities, With<ExtractedPointLight>>,
directional_light_entities: Query<&CascadesVisibleEntities, With<ExtractedDirectionalLight>>,
spot_light_entities: Query<&VisibleEntities, With<ExtractedPointLight>>,
spot_light_entities: Query<&VisibleMeshEntities, With<ExtractedPointLight>>,
) where
M::Data: PartialEq + Eq + Hash + Clone,
{
Expand Down Expand Up @@ -1218,7 +1218,7 @@ pub fn queue_shadows<M: Material>(
// NOTE: Lights with shadow mapping disabled will have no visible entities
// so no meshes will be queued

for entity in visible_entities.iter::<WithMesh>().copied() {
for entity in visible_entities.iter().copied() {
let Some(mesh_instance) = render_mesh_instances.render_mesh_queue_data(entity)
else {
continue;
Expand Down