1#[cfg(cpu)]
3mod cpu;
4#[cfg(cpu)]
5pub use cpu::*;
6
7pub mod shader {
8 use crabslab::{Id, Slab};
9 use glam::{Vec2, Vec3Swizzles, Vec4, Vec4Swizzles};
10 use spirv_std::{arch::IndexUnchecked, spirv};
11
12 use crate::{
13 draw::DrawIndirectArgs, geometry::shader::GeometryDescriptor,
14 primitive::shader::PrimitiveDescriptor, sdf, transform::shader::TransformDescriptor,
15 };
16 #[spirv(vertex)]
18 pub fn debug_overlay_vertex(
19 #[spirv(vertex_index)] vertex_id: u32,
20 #[spirv(position)] clip_pos: &mut Vec4,
21 ) {
22 *clip_pos = crate::math::CLIP_SPACE_COORD_QUAD_CCW[vertex_id as usize % 6];
23 }
24
25 #[spirv(fragment)]
29 pub fn debug_overlay_fragment(
30 #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] slab: &[u32],
31 #[spirv(storage_buffer, descriptor_set = 0, binding = 1)] draw_calls: &[DrawIndirectArgs],
32 #[spirv(frag_coord)] frag_coord: Vec4,
33 frag_color: &mut Vec4,
34 ) {
35 let camera_id_id = Id::from(GeometryDescriptor::OFFSET_OF_CAMERA_ID);
36 let camera_id = slab.read_unchecked(camera_id_id);
37 let camera = slab.read_unchecked(camera_id);
38 let resolution_id = Id::from(GeometryDescriptor::OFFSET_OF_RESOLUTION);
39 let viewport_size = slab.read_unchecked(resolution_id);
40
41 *frag_color = Vec4::ZERO;
42
43 for i in 0..draw_calls.len() {
44 let draw_call = unsafe { draw_calls.index_unchecked(i) };
45 let primitive_id: Id<PrimitiveDescriptor> =
46 Id::<PrimitiveDescriptor>::new(draw_call.first_instance);
47 let transform_id =
48 slab.read_unchecked(primitive_id + PrimitiveDescriptor::OFFSET_OF_TRANSFORM_ID);
49 let mut model = TransformDescriptor::IDENTITY;
50 slab.read_into_if_some::<TransformDescriptor>(transform_id, &mut model);
51 let bounds = slab.read_unchecked(primitive_id + PrimitiveDescriptor::OFFSET_OF_BOUNDS);
52
53 let (_, sphere_in_world_coords) = bounds.is_inside_camera_view(&camera, model);
54 let sphere_aabb = sphere_in_world_coords.project_onto_viewport(
55 &camera,
56 Vec2::new(viewport_size.x as f32, viewport_size.y as f32),
57 );
58
59 let sdf_circle = sdf::Box {
60 center: sphere_aabb.center().xy(),
61 half_extent: (sphere_aabb.max.xy() - sphere_aabb.min.xy()) * 0.5,
62 };
63
64 let distance = sdf_circle.distance(frag_coord.xy() + 0.5);
65
66 let alpha = crate::math::step_le(sphere_aabb.max.z, 1.0);
70 if distance.abs() < 0.5 {
71 *frag_color = Vec4::new(0.0, 0.0, 0.0, 1.0 * alpha);
72 } else if distance.abs() <= 2.0 {
73 *frag_color = Vec4::new(1.0, 1.0, 1.0, 0.5 * alpha);
74 } else if distance.abs() <= 3.0 {
75 *frag_color = Vec4::new(0.5, 0.5, 0.5, 1.0 * alpha);
76 }
77 }
78 }
79}