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_and_params: vec4<f32>,
11 @location(1) fill: vec4<f32>,
12 @location(2) border: vec4<f32>,
13 @location(3) @interpolate(flat) e0: vec4<f32>,
14 @location(4) @interpolate(flat) e1: vec4<f32>,
15 @location(5) @interpolate(flat) e2: vec4<f32>,
16 @location(6) @interpolate(flat) e3: vec4<f32>,
17 @location(7) @interpolate(flat) e4: vec4<f32>,
18 @location(8) @interpolate(flat) e5: vec4<f32>,
19 @location(9) @interpolate(flat) e6: vec4<f32>,
20 @location(10) @interpolate(flat) e7: vec4<f32>,
21};
22
23const CORNERS: array<vec2<f32>, 6> = array<vec2<f32>, 6>(
24 vec2<f32>(0.0, 0.0),
25 vec2<f32>(1.0, 0.0),
26 vec2<f32>(0.0, 1.0),
27 vec2<f32>(1.0, 0.0),
28 vec2<f32>(1.0, 1.0),
29 vec2<f32>(0.0, 1.0),
30);
31
32@vertex
33fn vs(
34 @builtin(vertex_index) vid: u32,
35 @location(0) rect_xywh: vec4<f32>,
36 @location(1) fill: vec4<f32>,
37 @location(2) border: vec4<f32>,
38 @location(3) params: vec4<f32>,
39 @location(4) e0: vec4<f32>,
40 @location(5) e1: vec4<f32>,
41 @location(6) e2: vec4<f32>,
42 @location(7) e3: vec4<f32>,
43 @location(8) e4: vec4<f32>,
44 @location(9) e5: vec4<f32>,
45 @location(10) e6: vec4<f32>,
46 @location(11) e7: vec4<f32>,
47) -> VsOut {
48 var corners = CORNERS;
49 let c = corners[vid];
50 let pos_px = rect_xywh.xy + c * rect_xywh.zw;
51 let ndc = vec2<f32>(
52 (pos_px.x / u.viewport_px.x) * 2.0 - 1.0,
53 1.0 - (pos_px.y / u.viewport_px.y) * 2.0,
54 );
55 var out: VsOut;
56 out.clip = vec4<f32>(ndc, 0.0, 1.0);
57 out.pos_and_params = vec4<f32>(pos_px, params.x, params.y);
58 out.fill = fill;
59 out.border = border;
60 out.e0 = e0;
61 out.e1 = e1;
62 out.e2 = e2;
63 out.e3 = e3;
64 out.e4 = e4;
65 out.e5 = e5;
66 out.e6 = e6;
67 out.e7 = e7;
68 return out;
69}
70
71fn plane_sd(p: vec2<f32>, plane: vec4<f32>) -> f32 {
72 return dot(plane.xy, p) - plane.z;
73}
74
75@fragment
76fn fs(in: VsOut) -> @location(0) vec4<f32> {
77 let p = in.pos_and_params.xy;
78 let count = in.pos_and_params.z;
79 let border_w = in.pos_and_params.w;
80 var sd = -1.0e30;
81 if (count > 0.5) { sd = max(sd, plane_sd(p, in.e0)); }
82 if (count > 1.5) { sd = max(sd, plane_sd(p, in.e1)); }
83 if (count > 2.5) { sd = max(sd, plane_sd(p, in.e2)); }
84 if (count > 3.5) { sd = max(sd, plane_sd(p, in.e3)); }
85 if (count > 4.5) { sd = max(sd, plane_sd(p, in.e4)); }
86 if (count > 5.5) { sd = max(sd, plane_sd(p, in.e5)); }
87 if (count > 6.5) { sd = max(sd, plane_sd(p, in.e6)); }
88 if (count > 7.5) { sd = max(sd, plane_sd(p, in.e7)); }
89 let aa = 0.5;
90 let cov_outer = clamp(0.5 - sd / aa, 0.0, 1.0);
91 if (cov_outer <= 0.0) {
92 discard;
93 }
94 var cov_inner = cov_outer;
95 if (border_w > 0.0) {
96 cov_inner = clamp(0.5 - (sd + border_w) / aa, 0.0, 1.0);
97 }
98 let border_cov = max(cov_outer - cov_inner, 0.0);
99 let bp = in.border * border_cov;
100 let fp = in.fill * cov_inner;
101 return bp + fp * (1.0 - bp.a);
102}