qskinny/examples/blurredbox/shaders/blurredbox.frag

79 lines
2.3 KiB
GLSL
Raw Normal View History

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;
// 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
uniform lowp vec2 blurRadius;
2022-09-01 13:56:20 +00:00
// normalized position of the fragment
varying lowp vec2 coord;
// 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;
uniform lowp float edgeSoftness;
2022-09-01 13:56:20 +00:00
lowp float effectiveRadius( in lowp vec4 radii, in lowp vec2 point )
{
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
}
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;
}
lowp vec2 rectAspectHalf = rectAspect / 2.0;
2022-09-01 13:56:20 +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
for(lowp float d = 0.0; d < Pi; d += Pi / blurDirections)
2022-09-01 13:56:20 +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
{
fragColor += texture2D( txr, coord + offset * blurRadius * i);
2022-09-01 13:56:20 +00:00
}
}
// Current corner radius
2022-09-01 13:56:20 +00:00
lowp float cornerRadius = effectiveRadius(rectCornerRadii, coord);
// 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;
// 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
}
// further reading
// - https://iquilezles.org/articles/distfunctions
// - https://www.shadertoy.com/view/Xltfzj