GLSL Beginner Series: A Journey from Your First Shader to Procedural Animation
Creating Soft Glows and Radial Gradients with smoothstep()
Not every shape in computer graphics has a hard edge.
Think about a flashlight shining in the dark.
A light bulb.
A glowing portal.
The sun.
Even a shadow gradually fades instead of stopping suddenly.
To create these kinds of effects, we need something smoother than a simple circle.
Fortunately, we've already learned the perfect tool.
The smoothstep() function.
Combined with distance(), it allows us to create radial gradients and realistic glows using only a few lines of code.
What Is a Radial Gradient?
Earlier in the series, we created gradients that moved from left to right using UV coordinates.
A radial gradient is different.
Instead of changing from one side of the screen to the other, it changes as you move away from a single point.
Imagine dropping a pebble into a calm lake.
The waves spread outward equally in every direction.
A radial gradient behaves in much the same way.
Measuring the Distance
Everything starts with measuring how far each pixel is from the center.
vec2 center = vec2(0.5);
float d = distance(vUv, center);
Pixels close to the center have small values.
Pixels farther away have larger values.
Instead of turning those values into a hard circle, we'll let them fade smoothly.
Our First Radial Gradient
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 vUv;
void main(){
vec2 center = vec2(0.5);
float d = distance(vUv, center);
float gradient = 1.0 - d;
gl_FragColor = vec4(vec3(gradient), 1.0);
}
The center appears bright.
As the distance increases, the brightness gradually fades until it reaches black.
Unlike a normal gradient, this one spreads evenly in every direction.
Creating a Glow
Now let's replace the simple subtraction with smoothstep().
float glow = 1.0 - smoothstep(0.0, 0.35, d);
This creates a soft glowing circle.
Instead of ending abruptly, the light gently disappears toward the edges.
This is one of the most common techniques used for lighting effects.
Understanding smoothstep()
Consider this line.
smoothstep(0.0, 0.35, d)
The first number tells GLSL where the fade begins.
The second number tells it where the fade finishes.
Everything between those values is smoothly blended.
Changing these numbers changes how quickly the glow disappears.
Making the Glow Larger
Increase the second value.
smoothstep(0.0, 0.50, d)
The light spreads farther across the screen.
Making the Glow Smaller
Reduce the second value.
smoothstep(0.0, 0.20, d)
The glow becomes much tighter around the center.
A single number completely changes the appearance.
Adding Color
Instead of grayscale, multiply the glow by a color.
vec3 color = vec3(0.3, 0.8, 1.0) * glow;
gl_FragColor = vec4(color, 1.0);
Now the glow becomes blue.
Try replacing the color values to create different moods.
Warm orange.
Bright green.
Deep purple.
Soft pink.
Combining Two Glows
Nothing limits us to one light source.
float glowA = 1.0 - smoothstep(0.0, 0.25, distance(vUv, vec2(0.35, 0.5)));
float glowB = 1.0 - smoothstep(0.0, 0.25, distance(vUv, vec2(0.65, 0.5)));
float glow = glowA + glowB;
Now two glowing circles appear.
Their light overlaps naturally.
This is how many procedural lighting effects begin.
Animating the Glow
Let's make the glow breathe.
float radius = 0.25 + sin(uTime) * 0.05;
float glow = 1.0 - smoothstep(0.0, radius, d);
The light slowly expands and contracts.
Because the animation uses sin(), the movement feels smooth and continuous.
Creating a Pulse
Instead of changing the radius a little, exaggerate it.
float radius = 0.20 + sin(uTime) * 0.10;
The glow now pulses much more dramatically.
This technique is often used for magical effects, energy orbs, and user interface animations.
Where Are Radial Gradients Used?
Radial gradients appear almost everywhere in graphics.
Some common examples include
- Light sources
- Glowing buttons
- Energy shields
- Fireballs
- Magic spells
- Lens flares
- Planet atmospheres
- User interface highlights
- Vignettes
- Particle effects
Although they look complicated, most begin with the same distance() and smoothstep() combination.
Try These Experiments
Create a small glow.
smoothstep(0.0, 0.15, d)
Create a large glow.
smoothstep(0.0, 0.50, d)
Animate the glow.
radius = 0.25 + sin(uTime) * 0.05
Create two glowing circles.
distance(vUv, vec2(0.3,0.5))
distance(vUv, vec2(0.7,0.5))
Try different colours and sizes to see how dramatically the effect changes.
A Small Challenge
Can you create these effects?
- A soft glowing moon.
- Two overlapping lights.
- A pulsing energy orb.
- A glowing loading indicator.
- A colorful light that slowly changes size.
Each one uses the same building blocks you've already learned.
What We Learned
Today we combined distance() and smoothstep() to create radial gradients and glowing effects.
Instead of drawing hard edges, we allowed light to fade naturally across the screen.
This simple technique is one of the foundations of procedural lighting and visual effects.
Leave GLSL Beginner Series: A Journey from Your First Shader to Procedural Animation to:
Read more #coding posts
Best Posts From hey2d
We have not curated any of hey2d's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.
More Posts From hey2d
- Fragment Shaders Made Simple: What gl-FragColor Does
- Understanding gl-Position: My First Real Vertex Shader
- Creating Procedural Galaxies and Nebulas in GLSL
- Creating a Procedural Night Sky and Stars in GLSL
- Creating Procedural Clouds in GLSL
- Adding Reflections and Highlights to Procedural Water in GLSL
- Creating Procedural Water in GLSL
- Creating Procedural Smoke in GLSL
- Creating Procedural Fire in GLSL
- Creating Procedural Wood Grain in GLSL
- Creating a Procedural Marble Texture in GLSL
- Domain Warping in GLSL: Distorting Noise to Create Organic Worlds
- Fractal Brownian Motion in GLSL: Building Rich Procedural Noise
- Understanding Gradient Noise in GLSL
- Creating Smooth Value Noise in GLSL
- Creating Random Values in GLSL: The Building Blocks of Procedural Graphics
- Combining Translation, Rotation, and Scaling in GLSL
- Scaling Shapes in GLSL: Making Procedural Graphics Grow and Shrink
- Rotating Shapes in GLSL: Understanding Coordinate Rotation
- Moving Shapes in GLSL: Understanding Coordinate Translation