Refactor check_light_mesh_visibility for performance #1 (#13905)

# Objective

- first part of #13900 

## Solution

- split `check_light_mesh_visibility `into
`check_dir_light_mesh_visibility `and
`check_point_light_mesh_visibility` for better review
This commit is contained in:
re0312 2024-06-18 11:22:54 +08:00 committed by GitHub
parent 41ad4e98de
commit 91cd84fea7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 58 additions and 33 deletions

View File

@ -368,7 +368,10 @@ impl Plugin for PbrPlugin {
.after(TransformSystem::TransformPropagate) .after(TransformSystem::TransformPropagate)
.after(SimulationLightSystems::AssignLightsToClusters), .after(SimulationLightSystems::AssignLightsToClusters),
check_visibility::<WithLight>.in_set(VisibilitySystems::CheckVisibility), check_visibility::<WithLight>.in_set(VisibilitySystems::CheckVisibility),
check_light_mesh_visibility (
check_dir_light_mesh_visibility,
check_point_light_mesh_visibility,
)
.in_set(SimulationLightSystems::CheckLightVisibility) .in_set(SimulationLightSystems::CheckLightVisibility)
.after(VisibilitySystems::CalculateBounds) .after(VisibilitySystems::CalculateBounds)
.after(TransformSystem::TransformPropagate) .after(TransformSystem::TransformPropagate)

View File

@ -638,22 +638,23 @@ pub fn update_spot_light_frusta(
} }
} }
pub fn check_light_mesh_visibility( fn shrink_entities(visible_entities: &mut Vec<Entity>) {
visible_point_lights: Query<&VisibleClusterableObjects>, // Check that visible entities capacity() is no more than two times greater than len()
mut point_lights: Query<( let capacity = visible_entities.capacity();
&PointLight, let reserved = capacity
&GlobalTransform, .checked_div(visible_entities.len())
&CubemapFrusta, .map_or(0, |reserve| {
&mut CubemapVisibleEntities, if reserve > 2 {
Option<&RenderLayers>, capacity / (reserve / 2)
)>, } else {
mut spot_lights: Query<( capacity
&SpotLight, }
&GlobalTransform, });
&Frustum,
&mut VisibleEntities, visible_entities.shrink_to(reserved);
Option<&RenderLayers>, }
)>,
pub fn check_dir_light_mesh_visibility(
mut directional_lights: Query< mut directional_lights: Query<
( (
&DirectionalLight, &DirectionalLight,
@ -682,22 +683,6 @@ pub fn check_light_mesh_visibility(
>, >,
visible_entity_ranges: Option<Res<VisibleEntityRanges>>, visible_entity_ranges: Option<Res<VisibleEntityRanges>>,
) { ) {
fn shrink_entities(visible_entities: &mut Vec<Entity>) {
// Check that visible entities capacity() is no more than two times greater than len()
let capacity = visible_entities.capacity();
let reserved = capacity
.checked_div(visible_entities.len())
.map_or(0, |reserve| {
if reserve > 2 {
capacity / (reserve / 2)
} else {
capacity
}
});
visible_entities.shrink_to(reserved);
}
let visible_entity_ranges = visible_entity_ranges.as_deref(); let visible_entity_ranges = visible_entity_ranges.as_deref();
// Directional lights // Directional lights
@ -804,6 +789,43 @@ pub fn check_light_mesh_visibility(
.for_each(shrink_entities); .for_each(shrink_entities);
} }
} }
}
pub fn check_point_light_mesh_visibility(
visible_point_lights: Query<&VisibleClusterableObjects>,
mut point_lights: Query<(
&PointLight,
&GlobalTransform,
&CubemapFrusta,
&mut CubemapVisibleEntities,
Option<&RenderLayers>,
)>,
mut spot_lights: Query<(
&SpotLight,
&GlobalTransform,
&Frustum,
&mut VisibleEntities,
Option<&RenderLayers>,
)>,
mut visible_entity_query: Query<
(
Entity,
&InheritedVisibility,
&mut ViewVisibility,
Option<&RenderLayers>,
Option<&Aabb>,
Option<&GlobalTransform>,
Has<VisibilityRange>,
),
(
Without<NotShadowCaster>,
Without<DirectionalLight>,
With<Handle<Mesh>>,
),
>,
visible_entity_ranges: Option<Res<VisibleEntityRanges>>,
) {
let visible_entity_ranges = visible_entity_ranges.as_deref();
for visible_lights in &visible_point_lights { for visible_lights in &visible_point_lights {
for light_entity in visible_lights.entities.iter().copied() { for light_entity in visible_lights.entities.iter().copied() {