Circles

float circle(vec2 position, float radius, float feather)
{
	return smoothstep(radius, radius + feather, length(position - vec2(0.5)));
}

How to use

Call circle() in the fragment() function.

COLOR.rgb = vec3( circle(UV, 0.2, 0.005) );

How it works

There are several ways you can do a circle. However, the core principle is the same – we define the center position of our circle and then ask each pixel how far from that center position it is. This will give the pixel a value between 0 – 1. We can then ask the pixel if its value is lower or higher than a predefined value. If it is higher we will set the pixel to white and if it is lower we will set it to black.

You can read a great explanation of how this works in The Book of Shaders’ article about shapes.

In the article, you can see that there are several ways to calculate the distance between the pixel and the circle position – length(), distance() and sqrt(). These methods all do square root calculations under the hood, which is not very performant. So if you want to do a lot of circles you can use the dot product for this instead.

float circle(vec2 position, float radius, float feather)
{
	return smoothstep(radius, radius + feather, dot(position, position) * 4.0);
}