1#define_import_path bevy_pbr::cluster 2#import bevy_pbr::clustered_forward::view_z_to_z_slice 5const CLUSTERABLE_OBJECT_TYPE_POINT_LIGHT: u32 = 0u; 6const CLUSTERABLE_OBJECT_TYPE_SPOT_LIGHT: u32 = 1u; 7const CLUSTERABLE_OBJECT_TYPE_REFLECTION_PROBE: u32 = 2u; 8const CLUSTERABLE_OBJECT_TYPE_IRRADIANCE_VOLUME: u32 = 3u; 9const CLUSTERABLE_OBJECT_TYPE_DECAL: u32 = 4u; 11const NDC_MIN: vec2<f32> = vec2<f32>(-1.0); 12const NDC_MAX: vec2<f32> = vec2<f32>(1.0); 18struct ClusterMetadata { 19 indirect_draw_params: ClusterRasterIndirectDrawParams, 21 clustered_light_count: u32, 22 reflection_probe_count: u32, 23 irradiance_volume_count: u32, 26 z_slice_list_capacity: u32, 29 farthest_z: atomic<u32>, 33struct ClusterRasterIndirectDrawParams { 35 instance_count: atomic<u32>, 45struct ClusterableObjectZSlice { 75fn cluster_space_object_aabb( 78 view_from_world: mat4x4<f32>, 79 clip_from_view: mat4x4<f32>, 80 view_from_world_scale: vec3<f32> 82 let position_view = (view_from_world * vec4(position, 1.0)).xyz; 83 let half_extents = radius * abs(view_from_world_scale); 85 var view_min = position_view - half_extents; 86 var view_max = position_view + half_extents; 97 view_min.z = min(view_min.z, -0.00001); 98 view_max.z = min(view_max.z, -0.00001); 105 let view_xymin_near = view_min; 106 let view_xymin_far = vec3(view_min.xy, view_max.z); 107 let view_xymax_near = vec3(view_max.xy, view_min.z); 108 let view_xymax_far = view_max; 110 let clip_xymin_near = clip_from_view * vec4(view_xymin_near, 1.0); 111 let clip_xymin_far = clip_from_view * vec4(view_xymin_far, 1.0); 112 let clip_xymax_near = clip_from_view * vec4(view_xymax_near, 1.0); 113 let clip_xymax_far = clip_from_view * vec4(view_xymax_far, 1.0); 115 let ndc_xymin_near = clip_xymin_near.xyz / clip_xymin_near.w; 116 let ndc_xymin_far = clip_xymin_far.xyz / clip_xymin_far.w; 117 let ndc_xymax_near = clip_xymax_near.xyz / clip_xymax_near.w; 118 let ndc_xymax_far = clip_xymax_far.xyz / clip_xymax_far.w; 120 var ndc_min = min(min(ndc_xymin_near, ndc_xymin_far), min(ndc_xymax_near, ndc_xymax_far)); 121 var ndc_max = max(max(ndc_xymin_near, ndc_xymin_far), max(ndc_xymax_near, ndc_xymax_far)); 124 ndc_min = vec3(clamp(ndc_min.xy, NDC_MIN, NDC_MAX), ndc_min.z); 125 ndc_max = vec3(clamp(ndc_max.xy, NDC_MIN, NDC_MAX), ndc_max.z); 128 return Aabb(vec3(ndc_min.xy, view_min.z), vec3(ndc_max.xy, view_max.z)); 132fn compute_view_from_world_scale(world_from_view: mat4x4<f32>) -> vec3<f32> { 133 let world_from_view_3x3 = mat3x3<f32>( 134 world_from_view[0].xyz, 135 world_from_view[1].xyz, 136 world_from_view[2].xyz 138 let det = determinant(world_from_view_3x3); 139 let scale = vec3<f32>( 140 length(world_from_view_3x3[0]) * sign(det), 141 length(world_from_view_3x3[1]), 142 length(world_from_view_3x3[2]) 144 return vec3<f32>(1.0) / scale; 150fn ndc_position_to_cluster( 151 cluster_dimensions: vec3<u32>, 152 cluster_factors: vec2<f32>, 153 is_orthographic: bool, 157 let frag_coord = clamp(ndc_p.xy * vec2(0.5, -0.5) + vec2(0.5), vec2(0.0), vec2(1.0)); 158 let xy = vec2<u32>(floor(frag_coord * vec2<f32>(cluster_dimensions.xy))); 159 let z_slice = view_z_to_z_slice(cluster_factors, cluster_dimensions.z, view_z, is_orthographic); 160 return clamp(vec3<u32>(xy, z_slice), vec3(0u), cluster_dimensions - vec3(1u)); 164fn calculate_sphere_cluster_bounds( 167 view_from_world: mat4x4<f32>, 168 clip_from_view: mat4x4<f32>, 169 view_from_world_scale: vec3<f32>, 170 cluster_dimensions: vec3<u32>, 171 cluster_factors: vec2<f32>, 172 is_orthographic: bool, 174 let aabb_ndc = cluster_space_object_aabb( 179 view_from_world_scale 182 let temp_min_cluster = ndc_position_to_cluster( 189 let temp_max_cluster = ndc_position_to_cluster( 197 let min_cluster = min(temp_min_cluster, temp_max_cluster); 198 let max_cluster = max(temp_min_cluster, temp_max_cluster); 200 return AabbU(min_cluster, max_cluster);