@@ -11,7 +11,6 @@ use bevy_render::{
11
11
primitives:: { Aabb , CubemapFrusta , Frustum , Sphere } ,
12
12
view:: { ComputedVisibility , RenderLayers , Visibility , VisibleEntities } ,
13
13
} ;
14
- use bevy_tasks:: ComputeTaskPool ;
15
14
use bevy_transform:: components:: GlobalTransform ;
16
15
use bevy_window:: Windows ;
17
16
@@ -486,7 +485,6 @@ fn cluster_to_index(cluster_dimensions: UVec3, cluster: UVec3) -> usize {
486
485
// NOTE: Run this before update_point_light_frusta!
487
486
pub fn assign_lights_to_clusters (
488
487
mut commands : Commands ,
489
- task_pool : Res < ComputeTaskPool > ,
490
488
mut global_lights : ResMut < VisiblePointLights > ,
491
489
mut views : Query < ( Entity , & GlobalTransform , & Camera , & Frustum , & mut Clusters ) > ,
492
490
lights : Query < ( Entity , & GlobalTransform , & PointLight ) > ,
@@ -510,116 +508,102 @@ pub fn assign_lights_to_clusters(
510
508
vec ! [ VisiblePointLights :: from_light_count( light_count) ; cluster_count] ;
511
509
let mut visible_lights_set = HashSet :: with_capacity ( light_count) ;
512
510
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
+ } ;
529
516
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) ;
613
603
}
614
604
}
615
- indices_entities
616
- } ) ;
605
+ }
617
606
}
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) ;
623
607
}
624
608
625
609
for cluster_lights in & mut clusters_lights {
0 commit comments