One of the biggest advantages of procedural graphics is that simple shapes can be combined to create much more complicated ones.
Instead of drawing an image, we build it one piece at a time.
Think of it like building with LEGO bricks.
One brick is simple.
A handful of bricks can become a house, a car, or even an entire city.
Procedural shaders work in exactly the same way.
Today we'll learn how to combine circles, rings, and gradients to build more complex graphics.
Every Shape Is Just a Number
When we created a circle, the result wasn't actually a shape.
It was a number.
float circle = 1.0 - step(0.25, distance(vUv, vec2(0.5)));
Pixels inside the circle received the value 1.0.
Pixels outside received 0.0.
Those numbers can be added, subtracted, or multiplied just like any other values.
That simple idea allows us to build almost anything.
Combining Two Circles
Let's place two circles next to each other.
float circleA = 1.0 - step(
0.18,
distance(vUv, vec2(0.35, 0.5))
);
float circleB = 1.0 - step(
0.18,
distance(vUv, vec2(0.65, 0.5))
);
Each one is created independently.
Now let's combine them.
float shape = circleA + circleB;
Both circles appear together.
Instead of drawing one object, we've created two.
Understanding Addition
Adding procedural shapes is similar to placing stickers on top of each other.
If either shape exists, the final result also exists.
Addition creates a union of shapes.
This is one of the most common techniques in procedural graphics.
Subtracting Shapes
What happens if we subtract one shape from another?
float shape = circleA - circleB;
Where the second circle overlaps the first, part of the shape disappears.
This technique is useful for cutting holes, creating crescents, and designing more interesting silhouettes.
Multiplying Shapes
Multiplication behaves differently.
float shape = circleA * circleB;
Only the overlapping area remains visible.
Everything else disappears.
This creates an intersection between the two shapes.
A Complete Example
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 vUv;
void main(){
float circleA = 1.0 - step(
0.18,
distance(vUv, vec2(0.40, 0.5))
);
float circleB = 1.0 - step(
0.18,
distance(vUv, vec2(0.60, 0.5))
);
float shape = circleA + circleB;
gl_FragColor = vec4(vec3(shape), 1.0);
}
Although each circle is simple, together they begin to form more interesting graphics.
Creating a Capsule Shape
Move the circles closer together.
vec2(0.45, 0.5)
vec2(0.55, 0.5)
Now they overlap.
Instead of looking like two separate circles, they begin to resemble a capsule.
This simple trick appears in many procedural user interface elements.
Combining Rings
The same technique works with rings.
float ringA = outerA - innerA;
float ringB = outerB - innerB;
float shape = ringA + ringB;
Now two outlined circles appear together.
This can become a radar display or a futuristic interface.
Mixing Glows
Earlier we created glowing circles.
Now combine them.
float glow = glowA + glowB;
The light naturally blends where the two glows overlap.
Many lighting effects begin with exactly this idea.
Animating Individual Shapes
Nothing says every shape must move the same way.
vec2 centerA = vec2(
0.35 + sin(uTime) * 0.10,
0.5
);
vec2 centerB = vec2(
0.65,
0.5 + cos(uTime) * 0.10
);
Each circle now moves independently.
By combining animated shapes, much richer effects become possible.
Where Is This Technique Used?
Combining procedural shapes is one of the foundations of shader programming.
It appears in
- User interface elements
- Game icons
- Particle systems
- Loading indicators
- Procedural logos
- Radar displays
- Health bars
- Target markers
- HUD graphics
- Motion graphics
Many complex designs begin with only circles, rectangles, and gradients.
Try These Experiments
Create two circles.
circleA + circleB
Subtract one circle.
circleA - circleB
Show only the overlap.
circleA * circleB
Animate one circle.
sin(uTime)
Animate both circles independently.
sin(uTime)
cos(uTime)
Try changing their positions, sizes, and colours.
You'll be surprised how many unique designs you can create.
A Small Challenge
Can you create these effects?
- A pair of overlapping circles.
- A capsule shape.
- A glowing Venn diagram.
- A moving radar interface.
- A simple procedural logo made from circles.
Remember that every effect starts with a few simple building blocks.
What We Learned
Today we discovered that procedural shapes can be combined using ordinary mathematical operations.
Adding shapes creates unions.
Subtracting shapes cuts holes.
Multiplying shapes keeps only overlapping regions.
These techniques allow simple primitives to grow into much more complicated graphics.