git.lucas.co / cce-compositor
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 }