Understanding Gradient Noise in GLSL
Value noise was a huge improvement over random pixels.
Instead of abrupt jumps, neighboring values blended together.
Even so, every grid cell still had a slight square appearance.
To solve this problem, computer graphics researchers came up with another idea.
Instead of storing random values at the corners, why not store random directions?
That simple change led to a much smoother form of procedural noise called gradient noise.
Looking at Value Noise Again
Imagine a square divided into four corners.
Each corner stores a random number.
As you move across the square, those numbers blend together.
The blending is smooth, but the corners still influence the final result in a noticeable way.
This is why large value noise patterns sometimes reveal a faint grid.
A Different Idea
Instead of assigning a random number to every corner, assign a random direction.
Each corner now contains a small arrow.
Some arrows point upward.
Some point sideways.
Others point diagonally.
The arrows never change.
Only the way they influence nearby pixels changes.
Choosing a Gradient
Each grid corner generates a direction.
A simple example might look like this.
vec2 gradient = vec2(
cos(angle),
sin(angle)
);
Instead of storing brightness, each corner stores a unit vector.
Measuring the Local Position
Just as we did with value noise, we first determine our position inside the current grid cell.
vec2 cell = floor(vUv * 8.0);
vec2 local = fract(vUv * 8.0);
The grid remains exactly the same.
Only the corner information changes.
Calculating Influence
Each corner now measures how well its direction matches the pixel.
This is done using the dot product.
float influence =
dot(
gradient,
local
);
Instead of blending random brightness values, we're blending directional influence.
This creates much smoother transitions.
Blending the Corners
The four corner influences are blended exactly as before.
float bottom = mix(a, b, local.x);
float top = mix(c, d, local.x);
float noise = mix(bottom, top, local.y);
The interpolation stays the same.
Only the values being blended are different.
Smoothing the Interpolation
We'll also continue using the smoothing function.
local = local * local *
(3.0 - 2.0 * local);
This softens the transitions near every edge.
Why Does Gradient Noise Look Better?
Imagine walking across rolling hills.
Value noise feels like walking over small plateaus.
Gradient noise feels like walking across gentle slopes.
The changes become more continuous.
The grid becomes much harder to notice.
This is why gradient noise became the foundation for many later algorithms.
A Simplified Shader
A complete gradient noise implementation is longer than value noise because each corner needs its own direction vector.
A simplified version begins like this.
vec2 cell = floor(vUv * 8.0);
vec2 local = fract(vUv * 8.0);
local = local * local *
(3.0 - 2.0 * local);
Next, each corner generates a gradient direction instead of a random value.
Those directional influences are then blended together.
Although the mathematics becomes longer, the overall idea stays surprisingly simple.
Adding Colour
Gradient noise works beautifully with color gradients.
vec3 color = mix(
vec3(0.15,0.25,0.6),
vec3(0.9,0.95,1.0),
noise
);
The smooth transitions make the result resemble soft clouds or mist.
Animating Gradient Noise
The coordinates can still move over time.
vec2 uv = vUv;
uv += uTime * 0.05;
The entire noise field appears to drift smoothly across the screen.
This technique is often used for clouds, smoke, and magical effects.
Comparing Three Approaches
Let's compare everything we've learned so far.
Random values.
Every neighboring pixel changes abruptly.
Value noise.
Random values blend together smoothly, but the grid is still visible.
Gradient noise.
Directional information blends together, creating much more natural patterns.
Each step builds directly on the previous one.
Where Is Gradient Noise Used?
Gradient noise appears in many procedural graphics.
- Clouds.
- Smoke.
- Water.
- Fire.
- Fog.
- Terrain generation.
- Animated backgrounds.
- Particle systems.
- Procedural textures.
- Visual effects.
Many modern shaders begin with some variation of gradient noise.
Try These Experiments
Compare value noise with gradient noise.
Animate the coordinates.
Increase the grid size.
Decrease the grid size.
Apply different color gradients.
Observe how much smoother the transitions become.
A Small Challenge
Can you create these effects?
- Soft moving clouds.
- Animated fog.
- A magical energy field.
- Flowing water.
- A colorful procedural background.
Each effect starts with smooth gradient noise.
Leave Understanding Gradient Noise in GLSL 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