Creating Diagonal Gradients in GLSL Using UV Coordinates
Before continuing with this lesson, if you are joining this series for the first time, I highly recommend reading the complete overview of everything we have covered so far.
A Beginner's Journey Through GLSL So Far
@hey2d/a-beginners-journey-through-glsl-so-far-d2z
That article covers the foundations we have been building throughout this series, including:
- Drawing a solid color on the screen
- Understanding UV coordinates
- Horizontal and vertical gradients
- The
mix()function - The
clamp()function - Several small exercises that help build intuition instead of memorizing code
Once you are comfortable with those ideas, this lesson will feel like a natural next step.
From Straight Gradients to Diagonal Gradients
So far we have used either vUv.x or vUv.y to create gradients.
When we use:
float t = vUv.x;
the gradient moves from left to right.
When we use:
float t = vUv.y;
the gradient moves from bottom to top.
But what if we want both directions at the same time?
Instead of choosing one coordinate, we simply combine both.
float t = (vUv.x + vUv.y) * 0.5;
This single line creates a diagonal gradient.
Understanding the Formula
Let's look at it piece by piece.
vUv.x + vUv.y
Both coordinates range from 0 to 1.
Adding them together gives values between 0 and 2.
| x | y | Result |
|---|---|---|
| 0 | 0 | 0 |
| 1 | 0 | 1 |
| 0 | 1 | 1 |
| 1 | 1 | 2 |
The problem is that our color interpolation usually expects numbers between 0 and 1.
So we divide by two.
(vUv.x + vUv.y) * 0.5
Now the values are safely back inside the range we expect.
What Happens at Each Corner?
Thinking about the four corners makes the formula much easier to understand.
| Position | vUv.x | vUv.y | t |
|---|---|---|---|
| Bottom left | 0 | 0 | 0 |
| Top right | 1 | 1 | 1 |
| Top left | 0 | 1 | 0.5 |
| Bottom right | 1 | 0 | 0.5 |
Notice something interesting.
The bottom left corner is completely dark.
The top right corner becomes completely bright.
The other two corners sit exactly halfway between them.
Because of this, our eyes perceive a smooth diagonal transition across the screen.
The Exercise
The exercise originally looks like this.
float t = 0.0;
Since t never changes, every pixel receives exactly the same value.
The entire screen stays black.
Your task is simply to replace it with
float t = (vUv.x + vUv.y) * 0.5;
Nothing else needs to change.
Immediately the screen transforms from a flat color into a diagonal gradient.
This is another great reminder that even a single number can completely change the appearance of a shader.
Why Multiply by 0.5?
Many beginners ask why we multiply instead of simply writing
float t = vUv.x + vUv.y;
The answer is range.
vUv.x goes from 0 to 1.
vUv.y goes from 0 to 1.
Together they produce values from 0 to 2.
Most interpolation functions such as mix() are designed to work with values between 0 and 1.
Multiplying by 0.5 scales the range back down.
You can also think of it as taking the average of the two coordinates.
It Is Not a Perfect Diagonal
Although it looks diagonal, mathematically it is not measuring distance from one corner.
The top left and bottom right corners both have the same value.
That means they receive exactly the same brightness.
Even so, our eyes naturally interpret the result as a diagonal gradient because the brightness increases smoothly from one corner to the opposite corner.
Later in this series we will learn other techniques that create different diagonal and radial patterns.
Try This Variation
Now experiment with another formula.
float t = vUv.x * vUv.y;
Instead of adding the coordinates, this multiplies them together.
The result feels completely different.
Most of the image stays darker, and the brightness only starts increasing as both coordinates become larger.
This is a great exercise because it teaches an important lesson.
Addition and multiplication are not just mathematical operations.
Inside shaders they become artistic tools that create entirely different visual patterns.
Complete Example
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 vUv;
void main()
{
float t = (vUv.x + vUv.y) * 0.5;
vec3 color = vec3(t);
gl_FragColor = vec4(color, 1.0);
}
This shader creates a grayscale diagonal gradient where the bottom left corner starts black and the top right corner becomes white.
Leave Creating Diagonal Gradients in GLSL Using UV Coordinates to:
Read more #training 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
- GLSL Lesson 4: Reshaping Light and Shadow with pow()
- GLSL Lesson 3: Understanding clamp() by Breaking and Fixing Colors
- Gradients: When Color Learns About Position
- Your First Shader: Painting the Entire Screen One Color
- The Strange Case of vUv.st: Why GLSL Keeps Swapping Coordinate Names
- Lesson 9 — HSB: When Color Stops Being Fixed and Starts Becoming a Space
- Gradients, Distance, and Why Shaders Start With a Line
- Why Xbox and the Big Gaming Companies Are Actually Terrified
- Gaming Just Became the Biggest Entertainment Business on Earth
- The Strange Case of vUv.st: Why GLSL Keeps Swapping Coordinate Names