qskinny/src/nodes/shaders/arcshadow.frag

60 lines
1.7 KiB
GLSL
Raw Normal View History

2023-12-04 16:33:28 +00:00
uniform lowp float qt_Opacity;
2023-12-06 12:32:38 +00:00
// arc
uniform lowp vec4 rect; // arc's rectangle on screen in pixel x,y,w,h
uniform lowp float radius; // arc's radius [0.0, 1.0]
uniform lowp float thickness; // arc's thickness
uniform lowp float startAngle; // arc's start angle
uniform lowp float spanAngle; // arc's span angle
// shadow
uniform lowp vec4 color; // shadow's color
uniform lowp vec2 offset; // shadow's offset (x,y) : [-1.0, +1.0]x[-1.0,+1.0]
uniform lowp float extend; // shadow length around
2023-12-04 16:33:28 +00:00
float sdRing( in vec2 p, in vec2 n, in float r, in float th )
{
p.x = abs(p.x);
p = mat2(n.x,n.y,-n.y,n.x)*p;
return max( abs(length(p)-r)-th*0.5,
length(vec2(p.x,max(0.0,abs(r-p.y)-th*0.5)))*sign(p.x) );
}
void main()
{
// uniforms
float shadowSize = extend; // px >= 0.0
vec2 iResolution = rect.zw;
// normalized pixel coordinates
vec2 p = (2.0 * gl_FragCoord.xy - iResolution.xy) / iResolution.xy; // xy for ellipse
float shadowSizeUv = shadowSize / min(iResolution.x, iResolution.y);
float t = radians(abs(spanAngle) / 2.0);
vec2 cs = vec2(cos(t),sin(t));
// rotation
float ra = radians(startAngle + spanAngle / 2.0);
2023-12-05 14:13:31 +00:00
{
p = p + offset;
2023-12-04 16:33:28 +00:00
float sin_ra = sin(ra);
float cos_ra = cos(ra);
2023-12-05 14:13:31 +00:00
mat2 transform = mat2
(
cos_ra, -sin_ra,
sin_ra, cos_ra
);
p = transform * p;
2023-12-04 16:33:28 +00:00
}
// distance
float d = sdRing(p, cs, radius, thickness);
float e = 1.0 / shadowSizeUv;
// coloring
float v = 1.0 - abs(d) * e;
2023-12-05 15:10:37 +00:00
float a = d >= 0.0 && abs(d) < e ? v : 1.0; // alpha
2023-12-05 14:13:31 +00:00
gl_FragColor = vec4(color.rgb, 1.0) * a * qt_Opacity;
2023-12-04 16:33:28 +00:00
}