Another project
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 4.4 kB View raw
1struct Frame { 2 clip_from_world: mat4x4<f32>, 3 stroke_color: vec4<f32>, 4 construction: vec4<f32>, 5 pixels_per_mm: f32, 6 dash_period_px: f32, 7 dash_on_ratio: f32, 8 _pad: f32, 9}; 10 11struct Instance { 12 @location(0) center: vec2<f32>, 13 @location(1) radius_mm: f32, 14 @location(2) half_width_px: f32, 15 @location(3) start_rad: f32, 16 @location(4) sweep_rad: f32, 17 @location(5) aabb_min_mm: vec2<f32>, 18 @location(6) aabb_max_mm: vec2<f32>, 19 @location(7) pick_id: u32, 20 @location(8) style_bits: u32, 21}; 22 23struct VsOut { 24 @builtin(position) clip: vec4<f32>, 25 @location(0) local_px: vec2<f32>, 26 @location(1) radius_px: f32, 27 @location(2) half_width_px: f32, 28 @location(3) start_rad: f32, 29 @location(4) sweep_rad: f32, 30 @location(5) @interpolate(flat) style_bits: u32, 31 @location(6) @interpolate(flat) pick_id: u32, 32}; 33 34struct FsOut { 35 @location(0) color: vec4<f32>, 36 @location(1) pick_id: u32, 37}; 38 39@group(0) @binding(0) var<uniform> u: Frame; 40 41const CORNERS: array<vec2<f32>, 6> = array<vec2<f32>, 6>( 42 vec2<f32>(0.0, 0.0), 43 vec2<f32>(1.0, 0.0), 44 vec2<f32>(0.0, 1.0), 45 vec2<f32>(0.0, 1.0), 46 vec2<f32>(1.0, 0.0), 47 vec2<f32>(1.0, 1.0), 48); 49 50const TWO_PI: f32 = 6.283185307179586; 51const CONSTRUCTION_BIT: u32 = 1u; 52 53@vertex 54fn vs(@builtin(vertex_index) vid: u32, inst: Instance) -> VsOut { 55 var corners = CORNERS; 56 let corner = corners[vid]; 57 let expand_mm = (inst.half_width_px + 1.0) / u.pixels_per_mm; 58 let bbox_min = inst.aabb_min_mm - vec2<f32>(expand_mm, expand_mm); 59 let bbox_max = inst.aabb_max_mm + vec2<f32>(expand_mm, expand_mm); 60 let offset_mm = mix(bbox_min, bbox_max, corner); 61 let world_mm = inst.center + offset_mm; 62 let clip = u.clip_from_world * vec4<f32>(world_mm, 0.0, 1.0); 63 64 var out: VsOut; 65 out.clip = clip; 66 out.local_px = offset_mm * u.pixels_per_mm; 67 out.radius_px = inst.radius_mm * u.pixels_per_mm; 68 out.half_width_px = inst.half_width_px; 69 out.start_rad = inst.start_rad; 70 out.sweep_rad = inst.sweep_rad; 71 out.style_bits = inst.style_bits; 72 out.pick_id = inst.pick_id; 73 return out; 74} 75 76struct ArcPoint { 77 distance_px: f32, 78 along_px: f32, 79}; 80 81fn arc_sample(p: vec2<f32>, radius_px: f32, start_rad: f32, sweep_rad: f32) -> ArcPoint { 82 let r_px = length(p); 83 let full_circle = sweep_rad >= TWO_PI - 1.0e-4; 84 if (full_circle) { 85 let theta = atan2(p.y, p.x); 86 var delta = theta - start_rad; 87 delta = delta - floor(delta / TWO_PI) * TWO_PI; 88 var out: ArcPoint; 89 out.distance_px = abs(r_px - radius_px); 90 out.along_px = delta * radius_px; 91 return out; 92 } 93 let theta = atan2(p.y, p.x); 94 var delta = theta - start_rad; 95 delta = delta - floor(delta / TWO_PI) * TWO_PI; 96 var theta_nearest: f32; 97 var along_rad: f32; 98 if (delta <= sweep_rad) { 99 theta_nearest = theta; 100 along_rad = delta; 101 } else { 102 let to_end = delta - sweep_rad; 103 let to_start = TWO_PI - delta; 104 if (to_end < to_start) { 105 theta_nearest = start_rad + sweep_rad; 106 along_rad = sweep_rad; 107 } else { 108 theta_nearest = start_rad; 109 along_rad = 0.0; 110 } 111 } 112 let nearest = vec2<f32>(cos(theta_nearest), sin(theta_nearest)) * radius_px; 113 var out: ArcPoint; 114 out.distance_px = length(p - nearest); 115 out.along_px = along_rad * radius_px; 116 return out; 117} 118 119@fragment 120fn fs(in: VsOut) -> FsOut { 121 let sample = arc_sample(in.local_px, in.radius_px, in.start_rad, in.sweep_rad); 122 let aa = 0.5; 123 let coverage = 1.0 - smoothstep(in.half_width_px - aa, in.half_width_px + aa, sample.distance_px); 124 if (coverage <= 0.0) { 125 discard; 126 } 127 128 let is_construction = (in.style_bits & CONSTRUCTION_BIT) != 0u; 129 let dash_visible = !is_construction 130 || u.dash_period_px <= 0.0 131 || fract(sample.along_px / u.dash_period_px) <= u.dash_on_ratio; 132 let color_coverage = select(0.0, coverage, dash_visible); 133 134 let base = select(u.stroke_color, u.construction, is_construction); 135 let a = base.a * color_coverage; 136 137 var out: FsOut; 138 out.color = vec4<f32>(base.rgb * a, a); 139 out.pick_id = in.pick_id; 140 return out; 141}