Skip to content

Commit 4385a7a

Browse files
committed
Revert "bevy_pbr: Leverage ComputeTaskPool parallelism for assign_lights_to_clusters"
This kind of optimisation is more controversial so I think it should at least be part of a separate PR. This reverts commit 14b6f0a.
1 parent 867a368 commit 4385a7a

File tree

2 files changed

+92
-109
lines changed

2 files changed

+92
-109
lines changed

crates/bevy_pbr/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ bevy_ecs = { path = "../bevy_ecs", version = "0.6.0" }
2121
bevy_math = { path = "../bevy_math", version = "0.6.0" }
2222
bevy_reflect = { path = "../bevy_reflect", version = "0.6.0", features = ["bevy"] }
2323
bevy_render = { path = "../bevy_render", version = "0.6.0" }
24-
bevy_tasks = { path = "../bevy_tasks", version = "0.6.0" }
2524
bevy_transform = { path = "../bevy_transform", version = "0.6.0" }
2625
bevy_utils = { path = "../bevy_utils", version = "0.6.0" }
2726
bevy_window = { path = "../bevy_window", version = "0.6.0" }

crates/bevy_pbr/src/light.rs

Lines changed: 92 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use bevy_render::{
1111
primitives::{Aabb, CubemapFrusta, Frustum, Sphere},
1212
view::{ComputedVisibility, RenderLayers, Visibility, VisibleEntities},
1313
};
14-
use bevy_tasks::ComputeTaskPool;
1514
use bevy_transform::components::GlobalTransform;
1615
use bevy_window::Windows;
1716

@@ -486,7 +485,6 @@ fn cluster_to_index(cluster_dimensions: UVec3, cluster: UVec3) -> usize {
486485
// NOTE: Run this before update_point_light_frusta!
487486
pub fn assign_lights_to_clusters(
488487
mut commands: Commands,
489-
task_pool: Res<ComputeTaskPool>,
490488
mut global_lights: ResMut<VisiblePointLights>,
491489
mut views: Query<(Entity, &GlobalTransform, &Camera, &Frustum, &mut Clusters)>,
492490
lights: Query<(Entity, &GlobalTransform, &PointLight)>,
@@ -510,116 +508,102 @@ pub fn assign_lights_to_clusters(
510508
vec![VisiblePointLights::from_light_count(light_count); cluster_count];
511509
let mut visible_lights_set = HashSet::with_capacity(light_count);
512510

513-
let lights_vec = lights.iter().collect::<Vec<_>>();
514-
let indices_entities = task_pool.scope(|scope| {
515-
let clusters = &*clusters;
516-
for chunk in lights_vec.chunks(32) {
517-
scope.spawn(async move {
518-
let mut indices_entities = Vec::new();
519-
for (light_entity, light_transform, light) in chunk {
520-
let light_sphere = Sphere {
521-
center: light_transform.translation,
522-
radius: light.range,
523-
};
524-
525-
// Check if the light is within the view frustum
526-
if !frustum.intersects_sphere(&light_sphere) {
527-
continue;
528-
}
511+
for (light_entity, light_transform, light) in lights.iter() {
512+
let light_sphere = Sphere {
513+
center: light_transform.translation,
514+
radius: light.range,
515+
};
529516

530-
// Calculate an AABB for the light in view space, find the corresponding clusters for the min and max
531-
// points of the AABB, then iterate over just those clusters for this light
532-
let light_aabb_view = Aabb {
533-
center: (inverse_view_transform * light_sphere.center.extend(1.0))
534-
.xyz(),
535-
half_extents: Vec3::splat(light_sphere.radius),
536-
};
537-
let (light_aabb_view_min, light_aabb_view_max) =
538-
(light_aabb_view.min(), light_aabb_view.max());
539-
// Is there a cheaper way to do this? The problem is that because of perspective
540-
// the point at max z but min xy may be less xy in screenspace, and similar. As
541-
// such, projecting the min and max xy at both the closer and further z and taking
542-
// the min and max of those projected points addresses this.
543-
let (
544-
light_aabb_view_xymin_near,
545-
light_aabb_view_xymin_far,
546-
light_aabb_view_xymax_near,
547-
light_aabb_view_xymax_far,
548-
) = (
549-
light_aabb_view_min,
550-
light_aabb_view_min.xy().extend(light_aabb_view_max.z),
551-
light_aabb_view_max.xy().extend(light_aabb_view_min.z),
552-
light_aabb_view_max,
553-
);
554-
let (
555-
light_aabb_clip_xymin_near,
556-
light_aabb_clip_xymin_far,
557-
light_aabb_clip_xymax_near,
558-
light_aabb_clip_xymax_far,
559-
) = (
560-
camera.projection_matrix * light_aabb_view_xymin_near.extend(1.0),
561-
camera.projection_matrix * light_aabb_view_xymin_far.extend(1.0),
562-
camera.projection_matrix * light_aabb_view_xymax_near.extend(1.0),
563-
camera.projection_matrix * light_aabb_view_xymax_far.extend(1.0),
564-
);
565-
let (
566-
light_aabb_ndc_xymin_near,
567-
light_aabb_ndc_xymin_far,
568-
light_aabb_ndc_xymax_near,
569-
light_aabb_ndc_xymax_far,
570-
) = (
571-
light_aabb_clip_xymin_near.xyz() / light_aabb_clip_xymin_near.w,
572-
light_aabb_clip_xymin_far.xyz() / light_aabb_clip_xymin_far.w,
573-
light_aabb_clip_xymax_near.xyz() / light_aabb_clip_xymax_near.w,
574-
light_aabb_clip_xymax_far.xyz() / light_aabb_clip_xymax_far.w,
575-
);
576-
let (light_aabb_ndc_min, light_aabb_ndc_max) = (
577-
light_aabb_ndc_xymin_near
578-
.min(light_aabb_ndc_xymin_far)
579-
.min(light_aabb_ndc_xymax_near)
580-
.min(light_aabb_ndc_xymax_far),
581-
light_aabb_ndc_xymin_near
582-
.max(light_aabb_ndc_xymin_far)
583-
.max(light_aabb_ndc_xymax_near)
584-
.max(light_aabb_ndc_xymax_far),
585-
);
586-
let min_cluster = ndc_position_to_cluster(
587-
clusters.axis_slices,
588-
cluster_factors,
589-
is_orthographic,
590-
light_aabb_ndc_min,
591-
light_aabb_view_min.z,
592-
);
593-
let max_cluster = ndc_position_to_cluster(
594-
clusters.axis_slices,
595-
cluster_factors,
596-
is_orthographic,
597-
light_aabb_ndc_max,
598-
light_aabb_view_max.z,
599-
);
600-
let (min_cluster, max_cluster) =
601-
(min_cluster.min(max_cluster), min_cluster.max(max_cluster));
602-
for y in min_cluster.y..=max_cluster.y {
603-
for x in min_cluster.x..=max_cluster.x {
604-
for z in min_cluster.z..=max_cluster.z {
605-
let cluster_index =
606-
cluster_to_index(clusters.axis_slices, UVec3::new(x, y, z));
607-
let cluster_aabb = &clusters.aabbs[cluster_index];
608-
if light_sphere.intersects_obb(cluster_aabb, &view_transform) {
609-
indices_entities.push((cluster_index, *light_entity));
610-
}
611-
}
612-
}
517+
// Check if the light is within the view frustum
518+
if !frustum.intersects_sphere(&light_sphere) {
519+
continue;
520+
}
521+
522+
// Calculate an AABB for the light in view space, find the corresponding clusters for the min and max
523+
// points of the AABB, then iterate over just those clusters for this light
524+
let light_aabb_view = Aabb {
525+
center: (inverse_view_transform * light_sphere.center.extend(1.0)).xyz(),
526+
half_extents: Vec3::splat(light_sphere.radius),
527+
};
528+
let (light_aabb_view_min, light_aabb_view_max) =
529+
(light_aabb_view.min(), light_aabb_view.max());
530+
// Is there a cheaper way to do this? The problem is that because of perspective
531+
// the point at max z but min xy may be less xy in screenspace, and similar. As
532+
// such, projecting the min and max xy at both the closer and further z and taking
533+
// the min and max of those projected points addresses this.
534+
let (
535+
light_aabb_view_xymin_near,
536+
light_aabb_view_xymin_far,
537+
light_aabb_view_xymax_near,
538+
light_aabb_view_xymax_far,
539+
) = (
540+
light_aabb_view_min,
541+
light_aabb_view_min.xy().extend(light_aabb_view_max.z),
542+
light_aabb_view_max.xy().extend(light_aabb_view_min.z),
543+
light_aabb_view_max,
544+
);
545+
let (
546+
light_aabb_clip_xymin_near,
547+
light_aabb_clip_xymin_far,
548+
light_aabb_clip_xymax_near,
549+
light_aabb_clip_xymax_far,
550+
) = (
551+
camera.projection_matrix * light_aabb_view_xymin_near.extend(1.0),
552+
camera.projection_matrix * light_aabb_view_xymin_far.extend(1.0),
553+
camera.projection_matrix * light_aabb_view_xymax_near.extend(1.0),
554+
camera.projection_matrix * light_aabb_view_xymax_far.extend(1.0),
555+
);
556+
let (
557+
light_aabb_ndc_xymin_near,
558+
light_aabb_ndc_xymin_far,
559+
light_aabb_ndc_xymax_near,
560+
light_aabb_ndc_xymax_far,
561+
) = (
562+
light_aabb_clip_xymin_near.xyz() / light_aabb_clip_xymin_near.w,
563+
light_aabb_clip_xymin_far.xyz() / light_aabb_clip_xymin_far.w,
564+
light_aabb_clip_xymax_near.xyz() / light_aabb_clip_xymax_near.w,
565+
light_aabb_clip_xymax_far.xyz() / light_aabb_clip_xymax_far.w,
566+
);
567+
let (light_aabb_ndc_min, light_aabb_ndc_max) = (
568+
light_aabb_ndc_xymin_near
569+
.min(light_aabb_ndc_xymin_far)
570+
.min(light_aabb_ndc_xymax_near)
571+
.min(light_aabb_ndc_xymax_far),
572+
light_aabb_ndc_xymin_near
573+
.max(light_aabb_ndc_xymin_far)
574+
.max(light_aabb_ndc_xymax_near)
575+
.max(light_aabb_ndc_xymax_far),
576+
);
577+
let min_cluster = ndc_position_to_cluster(
578+
clusters.axis_slices,
579+
cluster_factors,
580+
is_orthographic,
581+
light_aabb_ndc_min,
582+
light_aabb_view_min.z,
583+
);
584+
let max_cluster = ndc_position_to_cluster(
585+
clusters.axis_slices,
586+
cluster_factors,
587+
is_orthographic,
588+
light_aabb_ndc_max,
589+
light_aabb_view_max.z,
590+
);
591+
let (min_cluster, max_cluster) =
592+
(min_cluster.min(max_cluster), min_cluster.max(max_cluster));
593+
for y in min_cluster.y..=max_cluster.y {
594+
for x in min_cluster.x..=max_cluster.x {
595+
for z in min_cluster.z..=max_cluster.z {
596+
let cluster_index =
597+
cluster_to_index(clusters.axis_slices, UVec3::new(x, y, z));
598+
let cluster_aabb = &clusters.aabbs[cluster_index];
599+
if light_sphere.intersects_obb(cluster_aabb, &view_transform) {
600+
global_lights_set.insert(light_entity);
601+
visible_lights_set.insert(light_entity);
602+
clusters_lights[cluster_index].entities.push(light_entity);
613603
}
614604
}
615-
indices_entities
616-
});
605+
}
617606
}
618-
});
619-
for (cluster_index, light_entity) in indices_entities.into_iter().flatten() {
620-
global_lights_set.insert(light_entity);
621-
visible_lights_set.insert(light_entity);
622-
clusters_lights[cluster_index].entities.push(light_entity);
623607
}
624608

625609
for cluster_lights in &mut clusters_lights {

0 commit comments

Comments
 (0)