I'm developing a shader that draws a circle in WebGL, and it seems to work, but I'm not sure how. Here is the vertex shader:
in vec2 a_unit;
uniform mat3 u_projection;
uniform vec3 u_transform;
out vec2 v_pos;
void main() {
v_pos = a_unit;
float r = u_transform.z;
float x = u_transform.x - r;
float y = u_transform.y - r;
float w = r * 2.0;
float h = r * 2.0;
mat3 world = mat3(
w, 0, 0,
0, h, 0,
x, y, 1
);
gl_Position = vec4(u_projection * world * vec3(a_unit, 1), 1);
}
And here's the fragment shader:
in vec2 v_pos;
uniform vec4 u_color;
uniform vec3 u_transform;
uniform mat3 u_projection;
out vec4 outputColor;
void main() {
vec2 dist = v_pos - 0.5;
if (dist.x * dist.x + dist.y * dist.y > .222) {
discard;
}
outputColor = u_color;
}
I pass in to the shader a u_projection matrix, which is just my camera. And I also pass in a u_transform vector, which is just the world coordinates (and world radius) of my circle.
So for example, u_transform might be something like (200, 300, 25) for drawing a circle at x: 200, y: 300, with radius: 25
Oh, and a_unit is just a unit quad:
[
0, 0,
0, 1,
1, 0,
1, 0,
0, 1,
1, 1,
]
The logic is that I just draw a rectangle and then clip out via discarding anything not within the radius. And thus a circle is drawn.
My confusion lies on this line:
if (dist.x * dist.x + dist.y * dist.y > .222) { discard; }
I came up with the value 0.222 by just guessing and checking over and over. I don't understand how it works though. Why is this magical number able to draw a circle?
I thought I would need to convert the radius into texture coordinates, but it doesn't seem like that is required? But I'm not sure why..
Why does this work to draw a circle with an arbitrary radius? And what is the proper value, because 0.222, while being close, is not the exact value. What is the proper value I should be using instead of 0.222 here?