Repository: bevyengine/bevy
File: crates/bevy_light/src/cluster/assign.rs (Rust)

Code before:
                                * clusters.dimensions.z
                                + z) as usize;

                            match clusterable_object.object_type {
                                ClusterableObjectType::SpotLight { .. } => {
                                    let (view_light_direction, angle_sin, angle_cos) =
                                        spot_light_dir_sin_cos.unwrap();
                                    for x in min_x..=max_x {
                                        // further culling for spot lights
                                        // get or initialize cluster bounding sphere
                                        let cluster_aabb_sphere =
                                            &mut cluster_aabb_spheres[cluster_index];
                                        let cluster_aabb_sphere =
                                            if let Some(sphere) = cluster_aabb_sphere {
                                                &*sphere
                                            } else {
                                                let aabb = compute_aabb_for_cluster(
                                                    first_slice_depth,
                                                    far_z,
                                                    clusters.tile_size.as_vec2(),
                                                    screen_size.as_vec2(),
                                                    view_from_clip,
                                                    is_orthographic,
                                                    clusters.dimensions,
                                                    UVec3::new(x, y, z),
                                                );
                                                let sphere = Sphere {
                                                    center: aabb.center,
                                                    radius: aabb.half_extents.length(),
                                                };
                                                *cluster_aabb_sphere = Some(sphere);
                                                cluster_aabb_sphere.as_ref().unwrap()
                                            };

                                        // test -- based on https://bartwronski.com/2017/04/13/cull-that-cone/
                                        let spot_light_offset = Vec3::from(
                                            view_clusterable_object_sphere.center
                                                - cluster_aabb_sphere.center,
                                        );
                                        let spot_light_dist_sq = spot_light_offset.length_squared();
                                        let v1_len = spot_light_offset.dot(view_light_direction);

                                        let distance_closest_point = (angle_cos
                                            * (spot_light_dist_sq - v1_len * v1_len).sqrt())
                                            - v1_len * angle_sin;
                                        let angle_cull =
                                            distance_closest_point > cluster_aabb_sphere.radius;

                                        let front_cull = v1_len
                                            > cluster_aabb_sphere.radius
                                                + clusterable_object.range

Review comment (performance):
Would there be a big performance impact to do it like this instead? I feel like compilers should optimize things like that anyway. It just feels a bit less likely to mess up in the future

```suggestion
                                        total_cluster_index_count += 1;
                                    }
```

Code after:
                                            distance_closest_point > cluster_aabb_sphere.radius;

                                        let front_cull = v1_len
                                            > cluster_aabb_sphere.radius
                                                + clusterable_object.range
                                                    * view_from_world_scale_max;
                                        let back_cull = v1_len < -cluster_aabb_sphere.radius;

                                        if !angle_cull && !front_cull && !back_cull {
                                            // this cluster is affected by the spot light
                                            clusters.clusterable_objects[cluster_index]
                                                .add_spot_light(clusterable_object.entity);
                                            total_cluster_index_count += 1;
                                        }
                                        cluster_index += clusters.dimensions.z as usize;
                                    }
                                }

                                ClusterableObjectType::PointLight { .. } => {
                                    for _ in min_x..=max_x {
                                        // all clusters within range are affected by point lights
                                        clusters.clusterable_objects[cluster_index]
                                            .add_point_light(clusterable_object.entity);
                                        cluster_index += clusters.dimensions.z as usize;
                                    }
                                    total_cluster_index_count += (max_x - min_x + 1) as usize;
                                }

                                ClusterableObjectType::ReflectionProbe => {
                                    // Reflection probes currently affect all
                                    // clusters in their bounding sphere.
                                    //
                                    // TODO: Cull more aggressively based on the
                                    // probe's OBB.
                                    for _ in min_x..=max_x {
                                        clusters.clusterable_objects[cluster_index]
                                            .add_reflection_probe(clusterable_object.entity);
                                        cluster_index += clusters.dimensions.z as usize;
                                    }
                                    total_cluster_index_count += (max_x - min_x + 1) as usize;
                                }

                                ClusterableObjectType::IrradianceVolume => {
                                    // Irradiance volumes currently affect all
                                    // clusters in their bounding sphere.
                                    //
                                    // TODO: Cull more aggressively based on the
                                    // probe's OBB.
                                    for _ in min_x..=max_x {
                                        clusters.clusterable_objects[cluster_index]
                                            .add_irradiance_volume(clusterable_object.entity);