Circles, boxes & lines
Measure each pixel's distance to a point, a box or a line, and cut a shape out of it with a threshold.
Cards
2 live examples to tweak, learn and copy.
How it works
A fragment shader can’t draw a circle the way a drawing app does. There is no “circle” command. Every pixel runs the same code on its own and decides one thing: what color am I? A shape appears when that decision depends on where the pixel is.
The recipe has two parts. First, turn the pixel’s UVA 2D position on a surface or the screen, usually from 0 to 1 on both axes. Shaders draw shapes and patterns as functions of it. UV coordinates A 2D position on a surface or the screen, usually from 0 to 1 on both axes. Shaders draw shapes and patterns as functions of it. Vector A group of two to four numbers handled as one value (vec2, vec3, vec4). The same type holds a position, a direction, a color or a UV. Smoothstep A soft threshold. It is 0 below the first edge, 1 above the second, and follows an S-shaped curve with flat ends in between.uv = gl_FragCoord.xy / resolutionstep gives a jagged edge; a
smoothstepA soft threshold. It is 0 below the first edge, 1 above the second, and follows an S-shaped curve with flat ends in between.t = clamp((x − e0) / (e1 − e0), 0, 1); s = t² (3 − 2t)
Everything after that is about what you feed the threshold. Take the absolute difference from the radius and the disc
becomes a ring. Let the radius follow a sine of time and the ring breathes. The same measure, combined with others, is
the start of the signed distance fieldsA function that returns how far a point is from the edge of a shape, negative inside and positive outside. Zero is the outline itself. Signed distance field (SDF) A function that returns how far a point is from the edge of a shape, negative inside and positive outside. Zero is the outline itself.circle(p) = |p| − r
Engines and tools rarely ship this as one node because it is so small: a length and a smoothstep, or a Distance node
and a SmoothStep node in a graph. That is also why it ports everywhere unchanged.
Further reading
- step (opens in a new tab)Reference
- smoothstep (opens in a new tab)Reference
- Shaping functions (opens in a new tab)Book
- gl_FragCoord (opens in a new tab)Reference
- Uniforms (opens in a new tab)Book
- UV mapping (opens in a new tab)Reference
- Euclidean vector (opens in a new tab)Reference
- length (opens in a new tab)Reference
- normalize (opens in a new tab)Reference
- Shapes (opens in a new tab)Book
- 2D distance functions (opens in a new tab)Article
- Smoothstep (opens in a new tab)Reference
- sin (opens in a new tab)Reference
- abs (opens in a new tab)Reference
- Sine wave (opens in a new tab)Reference