Moving Gradient
The gradient scrolls endlessly from left to right. The whole effect comes from one line:
Let's break it down.
What fract does
fract(x) returns only the fractional part of a number — it drops everything before the decimal point:
fract(0.3)→ 0.3fract(1.7)→ 0.7fract(2.0)→ 0.0
No matter how large the input gets, the output always stays between 0.0 and 1.0 — and it wraps. Think of it like a clock that resets to 0 when it hits 12.
Adding u_time makes it move
vUv.x is the pixel's horizontal position, ranging from 0.0 (left) to 1.0 (right).
u_time * 0.2 grows over time. Adding it to vUv.x and then taking fract shifts the entire gradient to the right — when any value exceeds 1.0 and wraps around, the content reappears on the left, creating seamless scrolling.
0.2 controls the speed: larger values scroll faster.
How the gradient is generated
mix(A, B, t) linearly interpolates between color A and color B:
t = 0.0→ 100% A (dark gray)t = 0.5→ 50% A + 50% B (midpoint)t = 1.0→ 100% B (near white)
Since t scrolls over time, the gradient scrolls with it.
Try changing it
| Change | Effect |
|---|---|
u_time * 0.5 | Scrolls faster |
-u_time * 0.2 | Gradient scrolls left instead |
vUv.y + u_time * 0.2 | Gradient scrolls downward |
vUv.x * 2.0 + u_time * 0.2 | Gradient repeats twice, tighter pattern |
Exercise
The exercise canvas shows a static gradient. Change float t = vUv.x to use fract and u_time so the gradient scrolls to the right.
Answer Breakdown
vUv.xis each pixel's horizontal position+ u_time * 0.2shifts that position forward over timefract(...)wraps anything above 1.0 back to 0.0, creating seamless looping
The starting code has t = vUv.x, so the gradient is static. Adding fract and u_time shifts all t values each frame, making the gradient scroll.
Try changing 0.2 to 1.0 — the scroll becomes much faster and the gradient visibly sweeps across the canvas.