1precision highp float;
2
3uniform float uTime;
4uniform vec2 uResolution;
5uniform float uStep;
6
7// GLSL reads top → bottom — helpers must be declared before main() uses them.
8
9// Cosine palette (Inigo Quilez) — smooth rainbow from one formula.
10// Think of t (0–1) as position across the canvas; returns an RGB colour.
11//
12// a = baseline colour (offset)
13// b = amplitude — how far each channel swings from a
14// c = frequency — how many colour cycles across t
15// d = phase — shifts where red/green/blue peaks land
16//
17// cos() waves on R, G, B — same shape as mix(), but continuous and automatic.
18vec3 cosinePalette(float t) {
19 vec3 a = vec3(0.5);
20 vec3 b = vec3(0.5);
21 vec3 c = vec3(1.0);
22 vec3 d = vec3(0.0, 0.33, 0.67);
23 return a + b * cos(6.28318 * (c * t + d));
24}
25
26void main() {
27 // Normalise pixel position to 0–1 across the canvas (same idea as iteration 1)
28 vec2 uv = gl_FragCoord.xy / uResolution.xy;
29
30 // Iteration 1 — map UV coordinates to colour
31 if (uStep < 1.5) {
32 // Red channel = how far right (uv.x), green = how far up (uv.y)
33 gl_FragColor = vec4(uv.x, uv.y, 0.0, 1.0);
34 return;
35 }
36
37 // Iteration 2 — horizontal mix() gradient
38 if (uStep < 2.5) {
39 // vec3 is an RGB colour: (red, green, blue), each value 0.0–1.0
40 vec3 left = vec3(1.0, 0.0, 0.84); // magenta at the left edge
41 vec3 right = vec3(0.0, 0.9, 1.0); // cyan at the right edge
42
43 // mix(a, b, t) blends from colour a to colour b.
44 // t = 0.0 → all a (left). t = 1.0 → all b (right). t = 0.5 → halfway.
45 // uv.x is our t: 0 on the left, 1 on the right, so we get a smooth horizontal gradient.
46 vec3 col = mix(left, right, uv.x);
47
48 gl_FragColor = vec4(col, 1.0);
49 return;
50 }
51
52 // Iteration 3 — ROYGBIV rainbow, six mix() calls
53 // I chose this on purpose: simple to read, same idea as iteration 2 repeated.
54 if (uStep < 3.5) {
55 vec3 red = vec3(1.0, 0.0, 0.0);
56 vec3 orange = vec3(1.0, 0.5, 0.0);
57 vec3 yellow = vec3(1.0, 1.0, 0.0);
58 vec3 green = vec3(0.0, 1.0, 0.0);
59 vec3 blue = vec3(0.0, 0.0, 1.0);
60 vec3 indigo = vec3(0.29, 0.0, 0.51);
61 vec3 violet = vec3(0.56, 0.0, 1.0);
62
63 // Canvas width split into six equal slices — one mix() per slice
64 float seg = 1.0 / 6.0;
65 vec3 col;
66
67 if (uv.x < seg) {
68 col = mix(red, orange, uv.x / seg);
69 } else if (uv.x < seg * 2.0) {
70 col = mix(orange, yellow, (uv.x - seg) / seg);
71 } else if (uv.x < seg * 3.0) {
72 col = mix(yellow, green, (uv.x - seg * 2.0) / seg);
73 } else if (uv.x < seg * 4.0) {
74 col = mix(green, blue, (uv.x - seg * 3.0) / seg);
75 } else if (uv.x < seg * 5.0) {
76 col = mix(blue, indigo, (uv.x - seg * 4.0) / seg);
77 } else {
78 col = mix(indigo, violet, (uv.x - seg * 5.0) / seg);
79 }
80
81 gl_FragColor = vec4(col, 1.0);
82 return;
83 }
84
85 // Iteration 4 — reversed cosine rainbow
86 // This is how a pro would do it: one formula, no if chain.
87 if (uStep < 4.5) {
88 // 1.0 - uv.x flips direction — violet left, red right
89 vec3 col = cosinePalette(1.0 - uv.x);
90 gl_FragColor = vec4(col, 1.0);
91 return;
92 }
93}
94