1import package::meshlet::bindings::{ 7 meshlet_instance_uniforms, 9 meshlet_software_raster_indirect_args, 10 meshlet_hardware_raster_indirect_args, 11 meshlet_previous_raster_counts, 12 meshlet_raster_clusters, 13 meshlet_meshlet_cull_count_read, 14 meshlet_meshlet_cull_count_write, 15 meshlet_meshlet_cull_dispatch, 16 meshlet_meshlet_cull_queue, 18import package::meshlet::cull_shared::{ 21 lod_error_is_imperceptible, 23 should_occlusion_cull_aabb, 25import bevy_render::maths::affine3_to_square; 28@workgroup_size(128, 1, 1) 29fn cull_clusters(@builtin(global_invocation_id) global_invocation_id: vec3<u32>) { 30 if global_invocation_id.x >= meshlet_meshlet_cull_count_read { return; } 32 @if(MESHLET_FIRST_CULLING_PASS) 33 let meshlet_id = global_invocation_id.x; 35 let meshlet_id = constants.rightmost_slot - global_invocation_id.x; 36 let instanced_offset = meshlet_meshlet_cull_queue[meshlet_id]; 37 let instance_id = instanced_offset.instance_id; 38 let cull_data = &meshlet_cull_data[instanced_offset.offset]; 39 var aabb_error_offset = (*cull_data).aabb; 40 let aabb = get_aabb(&aabb_error_offset); 41 let error = get_aabb_error(&aabb_error_offset); 42 let lod_sphere = (*cull_data).lod_group_sphere; 44 let is_imperceptible = lod_error_is_imperceptible(lod_sphere, error, instance_id); 46 if !is_imperceptible || !aabb_in_frustum(aabb, instance_id) { return; } 50 if should_occlusion_cull_aabb(aabb, instance_id) { 51@if(MESHLET_FIRST_CULLING_PASS) { 52 let id = atomicAdd(&meshlet_meshlet_cull_count_write, 1u); 53 let value = InstancedOffset(instance_id, instanced_offset.offset); 54 meshlet_meshlet_cull_queue[constants.rightmost_slot - id] = value; 55 if ((id & 127u) == 0) { 56 atomicAdd(&meshlet_meshlet_cull_dispatch.x, 1u); 64 let world_from_local = affine3_to_square(meshlet_instance_uniforms[instance_id].world_from_local); 65 let clip_from_local = view.clip_from_world * world_from_local; 66 let projection = view.clip_from_world; 68 if projection[3][3] == 1.0 { 69 near = projection[3][2] / projection[2][2]; 71 near = projection[3][2]; 73 var screen_aabb = ScreenAabb(vec3<f32>(0.0), vec3<f32>(0.0)); 74 var sw_raster = project_aabb(clip_from_local, near, aabb, &screen_aabb); 76 let aabb_size = (screen_aabb.max.xy - screen_aabb.min.xy) * view.viewport.zw; 77 sw_raster = all(aabb_size <= vec2<f32>(64.0)); 83 buffer_slot = atomicAdd(&meshlet_software_raster_indirect_args.x, 1u); 84 buffer_slot += meshlet_previous_raster_counts[0]; 87 buffer_slot = atomicAdd(&meshlet_hardware_raster_indirect_args.instance_count, 1u); 88 buffer_slot += meshlet_previous_raster_counts[1]; 89 buffer_slot = constants.rightmost_slot - buffer_slot; 91 meshlet_raster_clusters[buffer_slot] = InstancedOffset(instance_id, instanced_offset.offset);