I'm working with WebGL and I'm trying to clip away what I'm drawing to draw a circle, but currently it's drawing an ellipse instead. Here is my fragment shader:
void main() {
vec4 c = vec4((u_matrix * vec3(u_center, 1)).xy, 0, 1); // center
float r = .25; // radius
bool withinRadius = pow(v_pos.x - c.x, 2.) + pow(v_pos.y - c.y, 2.) < r * r;
if (!withinRadius) { discard; }
gl_FragColor = vec4(1, 1, 1, 1);
}
I think the issue is that because my screen size is 1920x1200, the horizontal clip space that goes from -1.0 to +1.0 is wider than the vertical clip space that goes from -1.0 to +1.0. I think the solution might involve somehow normalizing the clip-space such that it is square, but I'm not exactly sure how to do that or what the recommended way to handle that is. How do you normally handle this scenario?
You have to scale either the x or the y component of the vector from the center of the circle to the fragment. Add a unfiorm variable or constant to the fragment shader which holds the aspect ratio (aspect = width/height
) or the resolution of the canvas and scale the x
component of the vector by aspect:
uniform vec2 u_resolution;
void main()
{
float aspect = u_resolution.x / u_resolution.y;
vec4 c = vec4((u_matrix * vec3(u_center, 1)).xy, 0, 1); // center
float r = .25; // radius
vec2 dist_vec = (v_pos.xy - c.xy) * vec2(aspect, 1.0);
if (dot(dist_vec, dist_vec) > r*r)
discard;
gl_FragColor = vec4(1, 1, 1, 1);
}
Note, I've used the Dot product to compute the square of the Euclidean distance:
dot(va, vb) == va.x*vb.x + va.y*vb.y