render/outline: Handler inner/outer radius properly and ceil thickness

This commit is contained in:
Victoria Brekenfeld 2025-12-22 17:59:56 +01:00 committed by Victoria Brekenfeld
parent d5734b4b68
commit 8f7dc7f00c
7 changed files with 78 additions and 25 deletions

View file

@ -9,29 +9,56 @@ varying vec2 v_coords;
uniform vec3 color;
uniform float thickness;
uniform vec4 radius;
uniform float scale;
float rounded_box(in vec2 p, in vec2 b, in vec4 r)
{
r.xy = (p.x > 0.0) ? r.xy : r.zw;
r.x = (p.y > 0.0) ? r.x : r.y;
vec2 q = abs(p) - b + r.x;
return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r.x;
float rounding_alpha(vec2 coords, vec2 size, vec4 radius) {
vec2 center;
float r;
if (coords.x < radius.x && coords.y < radius.x) {
r = radius.x;
center = vec2(r, r);
} else if (size.x - radius.y < coords.x && coords.y < radius.y) {
r = radius.y;
center = vec2(size.x - r, r);
} else if (size.x - radius.z < coords.x && size.y - radius.z < coords.y) {
r = radius.z;
center = vec2(size.x - r, size.y - r);
} else if (coords.x < radius.w && size.y - radius.w < coords.y) {
r = radius.w;
center = vec2(r, size.y - r);
} else {
return 1.0;
}
float dist = distance(coords, center);
float half_px = 0.5 / scale;
return 1.0 - smoothstep(r - half_px, r + half_px, dist);
}
void main() {
vec2 center = size / 2.0;
vec2 location = v_coords * size;
vec4 mix_color;
float distance = rounded_box(location - center, (size / 2.0) - (thickness / 2.0), radius);
float smoothedAlpha = 1.0 - smoothstep(-0.5, 0.5, abs(distance) - (thickness / 2.0));
float outer_alpha = rounding_alpha(v_coords * size, size, radius);
float inner_alpha = 1.0;
mix_color = mix(vec4(0.0, 0.0, 0.0, 0.0), vec4(color, alpha), smoothedAlpha);
#if defined(DEBUG_FLAGS)
if (thickness > 0.0) {
location -= vec2(thickness);
vec2 inner_size = size - vec2(thickness * 2.0);
if (0.0 <= location.x && location.x <= inner_size.x
&& 0.0 <= location.y && location.y <= inner_size.y)
{
vec4 inner_radius = radius - vec4(thickness);
inner_alpha = 1.0 - rounding_alpha(location, inner_size, inner_radius);
}
}
vec4 mix_color = mix(vec4(0.0, 0.0, 0.0, 0.0), vec4(color, alpha), outer_alpha * inner_alpha);
#if defined(DEBUG_FLAGS)
if (tint == 1.0)
mix_color = vec4(0.0, 0.3, 0.0, 0.2) + mix_color * 0.8;
#endif
#endif
gl_FragColor = mix_color;
}
}