Another project
1struct Frame {
2 viewport_px: vec2<f32>,
3 _pad: vec2<f32>,
4};
5
6@group(0) @binding(0) var<uniform> u: Frame;
7
8struct VsOut {
9 @builtin(position) clip: vec4<f32>,
10 @location(0) pos_px: vec2<f32>,
11 @location(1) @interpolate(flat) count_half: vec2<f32>,
12 @location(2) @interpolate(flat) color: vec4<f32>,
13 @location(3) @interpolate(flat) p0: vec4<f32>,
14 @location(4) @interpolate(flat) p1: vec4<f32>,
15 @location(5) @interpolate(flat) p2: vec4<f32>,
16 @location(6) @interpolate(flat) p3: vec4<f32>,
17 @location(7) @interpolate(flat) p4: vec4<f32>,
18};
19
20const CORNERS: array<vec2<f32>, 6> = array<vec2<f32>, 6>(
21 vec2<f32>(0.0, 0.0),
22 vec2<f32>(1.0, 0.0),
23 vec2<f32>(0.0, 1.0),
24 vec2<f32>(1.0, 0.0),
25 vec2<f32>(1.0, 1.0),
26 vec2<f32>(0.0, 1.0),
27);
28
29@vertex
30fn vs(
31 @builtin(vertex_index) vid: u32,
32 @location(0) rect_xywh: vec4<f32>,
33 @location(1) color: vec4<f32>,
34 @location(2) params: vec4<f32>,
35 @location(3) p0: vec4<f32>,
36 @location(4) p1: vec4<f32>,
37 @location(5) p2: vec4<f32>,
38 @location(6) p3: vec4<f32>,
39 @location(7) p4: vec4<f32>,
40) -> VsOut {
41 var corners = CORNERS;
42 let c = corners[vid];
43 let pos_px = rect_xywh.xy + c * rect_xywh.zw;
44 let ndc = vec2<f32>(
45 (pos_px.x / u.viewport_px.x) * 2.0 - 1.0,
46 1.0 - (pos_px.y / u.viewport_px.y) * 2.0,
47 );
48 var out: VsOut;
49 out.clip = vec4<f32>(ndc, 0.0, 1.0);
50 out.pos_px = pos_px;
51 out.count_half = params.xy;
52 out.color = color;
53 out.p0 = p0;
54 out.p1 = p1;
55 out.p2 = p2;
56 out.p3 = p3;
57 out.p4 = p4;
58 return out;
59}
60
61fn seg_dist(p: vec2<f32>, a: vec2<f32>, b: vec2<f32>) -> f32 {
62 let d = b - a;
63 let len2 = max(dot(d, d), 1.0e-12);
64 let t = clamp(dot(p - a, d) / len2, 0.0, 1.0);
65 return length(p - (a + t * d));
66}
67
68@fragment
69fn fs(in: VsOut) -> @location(0) vec4<f32> {
70 let p = in.pos_px;
71 let count = in.count_half.x;
72 let half_px = in.count_half.y;
73 var d = seg_dist(p, in.p0.xy, in.p0.zw);
74 if (count > 2.5) { d = min(d, seg_dist(p, in.p0.zw, in.p1.xy)); }
75 if (count > 3.5) { d = min(d, seg_dist(p, in.p1.xy, in.p1.zw)); }
76 if (count > 4.5) { d = min(d, seg_dist(p, in.p1.zw, in.p2.xy)); }
77 if (count > 5.5) { d = min(d, seg_dist(p, in.p2.xy, in.p2.zw)); }
78 if (count > 6.5) { d = min(d, seg_dist(p, in.p2.zw, in.p3.xy)); }
79 if (count > 7.5) { d = min(d, seg_dist(p, in.p3.xy, in.p3.zw)); }
80 if (count > 8.5) { d = min(d, seg_dist(p, in.p3.zw, in.p4.xy)); }
81 if (count > 9.5) { d = min(d, seg_dist(p, in.p4.xy, in.p4.zw)); }
82 let aa = 0.5;
83 let cov = clamp(0.5 - (d - half_px) / aa, 0.0, 1.0);
84 if (cov <= 0.0) {
85 discard;
86 }
87 return in.color * cov;
88}