2022-09-01 13:56:20 +00:00
|
|
|
// opacity of the rectangle
|
|
|
|
uniform lowp float rectOpacity;
|
|
|
|
// x = top left, y = top right, z = bottom right, w = bottom left
|
|
|
|
uniform lowp vec4 rectCornerRadii;
|
2022-09-14 11:04:25 +00:00
|
|
|
// the rectangle's aspect ratio
|
|
|
|
uniform lowp vec2 rectAspect;
|
|
|
|
|
2022-09-01 13:56:20 +00:00
|
|
|
// must be greater than 0.0!
|
|
|
|
uniform lowp float blurDirections;
|
|
|
|
// must be greater than 0.0!
|
|
|
|
uniform lowp float blurQuality;
|
|
|
|
// the radius for blurring
|
2022-09-14 11:04:25 +00:00
|
|
|
uniform lowp vec2 blurRadius;
|
2022-09-01 13:56:20 +00:00
|
|
|
|
|
|
|
// normalized position of the fragment
|
|
|
|
varying lowp vec2 coord;
|
|
|
|
|
2022-09-14 11:04:25 +00:00
|
|
|
// the texture with coordinates from top left (0.0,0.0) to bottom right (1.0,1.0)
|
2022-09-01 13:56:20 +00:00
|
|
|
uniform sampler2D txr;
|
|
|
|
|
2022-09-14 11:04:25 +00:00
|
|
|
uniform lowp float edgeSoftness;
|
|
|
|
|
2022-09-01 13:56:20 +00:00
|
|
|
lowp float effectiveRadius( in lowp vec4 radii, in lowp vec2 point )
|
2022-09-14 11:04:25 +00:00
|
|
|
{
|
|
|
|
if ( point.y < 0.5 )
|
|
|
|
return ( point.x < 0.5) ? radii.x : radii.y;
|
|
|
|
else
|
|
|
|
return ( point.x < 0.5) ? radii.z : radii.w;
|
2022-09-01 13:56:20 +00:00
|
|
|
}
|
|
|
|
|
2022-09-14 11:04:25 +00:00
|
|
|
lowp float roundedBoxSDF(lowp vec2 centerPosition, lowp vec2 size, lowp float radius)
|
2022-09-01 13:56:20 +00:00
|
|
|
{
|
|
|
|
return length( max( abs(centerPosition) - size + radius, 0.0) ) - radius;
|
|
|
|
}
|
|
|
|
|
|
|
|
void main()
|
|
|
|
{
|
|
|
|
if(rectOpacity == 0.0)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-09-14 11:04:25 +00:00
|
|
|
lowp vec2 rectAspectHalf = rectAspect / 2.0;
|
2022-09-01 13:56:20 +00:00
|
|
|
|
2022-09-14 11:04:25 +00:00
|
|
|
// Pixel color
|
|
|
|
lowp vec4 fragColorOrig = texture2D(txr, coord);
|
|
|
|
lowp vec4 fragColor = fragColorOrig;
|
2022-09-01 13:56:20 +00:00
|
|
|
|
|
|
|
// Blur calculations
|
|
|
|
const lowp float Pi = 6.28318530718; // constant for Pi*2
|
2022-09-14 11:04:25 +00:00
|
|
|
for(lowp float d = 0.0; d < Pi; d += Pi / blurDirections)
|
2022-09-01 13:56:20 +00:00
|
|
|
{
|
2022-09-14 11:04:25 +00:00
|
|
|
lowp vec2 offset = vec2(cos(d), sin(d));
|
|
|
|
for(lowp float i = 1.0 / blurQuality; i <= 1.0; i += 1.0 / blurQuality)
|
2022-09-01 13:56:20 +00:00
|
|
|
{
|
2022-09-14 11:04:25 +00:00
|
|
|
fragColor += texture2D( txr, coord + offset * blurRadius * i);
|
2022-09-01 13:56:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-14 11:04:25 +00:00
|
|
|
// Current corner radius
|
2022-09-01 13:56:20 +00:00
|
|
|
lowp float cornerRadius = effectiveRadius(rectCornerRadii, coord);
|
2022-09-14 11:04:25 +00:00
|
|
|
|
|
|
|
// Calculate distance to edge.
|
|
|
|
lowp float distance = roundedBoxSDF(coord * rectAspect - rectAspectHalf, rectAspectHalf, cornerRadius);
|
|
|
|
|
|
|
|
// Smooth the result (free antialiasing).
|
|
|
|
lowp float smoothedAlpha = 1.0 - smoothstep(0.0, 2.0 * edgeSoftness, distance);
|
2022-09-01 13:56:20 +00:00
|
|
|
|
|
|
|
// Output to screen
|
|
|
|
fragColor /= blurQuality * blurDirections - 15.0;
|
|
|
|
|
2022-09-14 11:04:25 +00:00
|
|
|
// Mix the original pixel coolor with the blurred
|
|
|
|
gl_FragColor = mix(fragColorOrig, vec4(fragColor.xyz, 1.0), smoothedAlpha) * rectOpacity;
|
2022-09-01 13:56:20 +00:00
|
|
|
}
|
2022-09-14 11:04:25 +00:00
|
|
|
|
|
|
|
// further reading
|
|
|
|
// - https://iquilezles.org/articles/distfunctions
|
|
|
|
// - https://www.shadertoy.com/view/Xltfzj
|