Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
scenefx/render/fx_renderer/shaders/quad_round.frag (2.7K)
1 precision highp float;
2
3 varying vec4 v_color;
4 varying vec2 v_texcoord;
5
6 uniform vec2 size;
7 uniform vec2 position;
8 uniform float radius_top_left;
9 uniform float radius_top_right;
10 uniform float radius_bottom_left;
11 uniform float radius_bottom_right;
12 uniform float fade_inset;
13 uniform int fade_mode;
14
15 uniform vec2 clip_size;
16 uniform vec2 clip_position;
17 uniform float clip_radius_top_left;
18 uniform float clip_radius_top_right;
19 uniform float clip_radius_bottom_left;
20 uniform float clip_radius_bottom_right;
21
22 float get_dist(vec2 q, float radius);
23 float corner_alpha(vec2 size, vec2 position, bool is_cutout,
24 float radius_tl, float radius_tr, float radius_bl, float radius_br);
25
26 void main() {
27 vec2 relative_pos = (gl_FragCoord.xy - (position + 0.5));
28 relative_pos.y = size.y - relative_pos.y;
29
30 // Bounding box check
31 /* if (relative_pos.x < -0.5 || relative_pos.y < -0.5
32 || relative_pos.x > size.x - 0.5 || relative_pos.y > size.y - 0.5) {
33 discard;
34 } */
35
36 float r_tl = radius_top_left;
37 float r_tr = radius_top_right;
38 float r_bl = radius_bottom_left;
39 float r_br = radius_bottom_right;
40
41 // Calculate corner distance
42 vec2 top_left = abs(relative_pos - (size - 1.0)) - (size - 1.0) + r_tl;
43 vec2 top_right = abs(relative_pos - vec2(0.0, size.y - 1.0)) - (size - 1.0) + r_tr;
44 vec2 bottom_left = abs(relative_pos - vec2(size.x - 1.0, 0.0)) - (size - 1.0) + r_bl;
45 vec2 bottom_right = abs(relative_pos) - (size - 1.0) + r_br;
46
47 float dist = max(
48 max(get_dist(top_left, r_tl), get_dist(top_right, r_tr)),
49 max(get_dist(bottom_left, r_bl), get_dist(bottom_right, r_br))
50 );
51
52 float result = smoothstep(-0.5, 0.5, dist);
53 float quad_corner_alpha = 1.0 - result;
54
55 // Clipping
56 float clip_corner_alpha = corner_alpha(
57 clip_size - 1.0,
58 clip_position + 0.5,
59 true,
60 clip_radius_top_left,
61 clip_radius_top_right,
62 clip_radius_bottom_left,
63 clip_radius_bottom_right
64 );
65
66 vec4 final_color = v_color;
67 if (fade_inset > 0.0) {
68 // Fade by distance to the ROUNDED outline — the same SDF that cuts
69 // the corners — not the straight edges. The old per-axis product
70 // formed a square-cornered onset at each corner that visually
71 // swamped the corner arcs whenever fade and radius were combined.
72 float edge_dist = -dist;
73
74 // Clamp to [0, fade_inset] and normalize
75 float factor = clamp(edge_dist / fade_inset, 0.0, 1.0);
76
77 if (fade_mode == 1) {
78 factor = smoothstep(0.0, 1.0, factor);
79 } else if (fade_mode == 2) {
80 factor = factor * factor;
81 } else if (fade_mode == 3) {
82 factor = 0.5 - 0.5 * cos(factor * 3.14159265);
83 } else if (fade_mode == 4) {
84 float x = 1.0 - factor;
85 factor = clamp((exp(-3.0 * x * x) - 0.049) / 0.951, 0.0, 1.0);
86 }
87
88 final_color *= pow(factor, 2.2);
89 }
90
91 gl_FragColor = final_color * quad_corner_alpha * clip_corner_alpha;
92 }