GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
src/vk/glyph.wgsl (1.6K)
1 // Glyph-atlas pipeline for the ash text stage. Mask glyphs are stored as
2 // white-with-alpha texels, color (emoji) glyphs as-is with a white vertex
3 // color — one multiply covers both.
4
5 @group(0) @binding(0) var t_atlas: texture_2d<f32>;
6 @group(0) @binding(1) var s_atlas: sampler;
7
8 struct VertexOutput {
9 @builtin(position) clip_position: vec4f,
10 @location(0) uv: vec2f,
11 @location(1) color: vec4f,
12 @location(2) clip_circle: vec3f,
13 @location(3) clip_extents: vec2f,
14 }
15
16 @vertex
17 fn vs_main(
18 @location(0) position: vec2f,
19 @location(1) uv: vec2f,
20 @location(2) color: vec4f,
21 @location(3) clip_circle: vec3f,
22 @location(4) clip_extents: vec2f,
23 ) -> VertexOutput {
24 var out: VertexOutput;
25 out.clip_position = vec4f(position, 0.0, 1.0);
26 out.uv = uv;
27 out.color = color;
28 out.clip_circle = clip_circle;
29 out.clip_extents = clip_extents;
30 return out;
31 }
32
33 @fragment
34 fn fs_main(in: VertexOutput) -> @location(0) vec4f {
35 // Rounded-rect SDF clip in framebuffer px: center clip_circle.xy, corner radius
36 // clip_circle.z, inner-box half-size clip_extents. Zero extents degenerate to the
37 // plain circle clip (the circular network pane's curved rim labels); a non-zero
38 // box clips plate children at the plate's rounded corners.
39 if (in.clip_circle.z > 0.0) {
40 let q = abs(in.clip_position.xy - in.clip_circle.xy) - in.clip_extents;
41 let d = length(max(q, vec2f(0.0))) - in.clip_circle.z;
42 if (d > 0.0) {
43 discard;
44 }
45 }
46 return in.color * textureSample(t_atlas, s_atlas, in.uv);
47 }