openglglslrounded-corners

GLSL Rounded Rectangle Corners Are Stretched


I'm programing a GUI library in openGL and decided to add rounded corners because I feel like it gives a much more professional look to the units. I've implemented the common

length(max(abs(p) - b, 0.0)) - radius

method and it almost works perfectly except for the fact tat the corners seems as though they are stretched:

enter image description here

My fragment shader:

in vec2 passTexCoords;

uniform vec4 color;
uniform int width;
uniform int height;
uniform int radius;    

void main() {
    fragment = color;

    vec2 pos = (abs(passTexCoords - 0.5) + 0.5) * vec2(width, height);

    float alpha = 1.0 - clamp(length(max(pos - (vec2(width, height) - radius), 0.0)) - radius, 0.0, 1.0);

    fragment.a = alpha;
}

The stretching does make sense to me but when I replace with

vec2 pos = (abs(passTexCoords - 0.5) + 0.5) * vec2(width, height) * vec2(scaleX, scaleY);

and

float alpha = 1.0 - clamp(length(max(pos - (vec2(width, height) * vec2(scaleX, scaleY) - radius), 0.0)) - radius, 0.0, 1.0);

(where scaleX and scaleY are scalars between 0.0 and 1.0 that represent the width and height of the rectangle relative to the screen) the rectangle almost completely disappears:

enter image description here


Solution

  • I assume the passTexCoords is a a texture coordinate in range [0, 1]. And that width and height is the size of the screen. And scaleX and scaleY is the ration of the green area to the size of the screen.
    Calculate the absolute position (pos) of the current fragment in relation to the center of the green area in pixel units:

    vec2 pos = (abs(passTexCoords - 0.5) + 0.5) * vec2(width*scaleX, height*scaleY);
    

    Calculate the distance from the center point of the arc, to the current fragment:

    vec2 arc_cpt_vec = max(pos - vec2(width*scaleX, height*scaleY) + radius, 0.0);
    

    If the length of the vector is greater than the radius, then the fragment has to be skipped:

    float alpha = length(arc_cpt_vec) > radius ? 0.0 : 1.0;