Lesson 1 of 10 · Shader patterns
Shapes
Rings, squares, diamonds. Each shape is a distance equation.
In Start Here every pixel asked what color am I? A shape answers a sharper question: how far am I from this edge?
Before measuring distances, a new tool: M. It is a vec2 that always holds the mouse position, normalized between 0 and 1, it comes from the browser and updates every frame. In the shader we translate it to the same space as p with one line:
vec2 m = (2.*M*R - R) / min(R.x, R.y);
Now m lives in the same world as p, the cursor is just another coordinate, ready to enter the equations.
Each shape is a distance function. length(p) - .65 is positive outside the ring, negative inside, and exactly zero on the edge. Same for the square and the diamond, only the way of measuring changes.
One equation. One shape. Three rulers for distance.
M comes from the browser, the mouse in normalized coordinates (0 to 1). m is M translated to the same space as p, where screen center is (0,0). That formula (2.*M*R - R) / min(R.x, R.y) you will see in every lesson with interaction.length(p), the straight ruler from center. The square measures with max, largest coordinate wins. The diamond measures with +, sum of both coordinates. Three rulers, three geometries..65 on the ring to .85 and the ring drifts away from center.The code
void main(){
vec2 p = (2.*gl_FragCoord.xy - R) / min(R.x, R.y);
vec2 m = (2.*M*R - R) / min(R.x, R.y);
vec3 col = vec3(0.025, 0.018, 0.035);
float dRing = abs(length(p) - .65);
vec2 sq = abs(p) - .42;
float dSquare = max(sq.x, sq.y);
float dDiamond = abs(p.x) + abs(p.y) - .25;
float hRing = exp(-abs(length(m) - .65) * 3.);
vec2 msq = abs(m) - .42;
float hSquare = exp(-abs(max(msq.x, msq.y)) * 3.);
float hDiamond = exp(-abs(abs(m.x) + abs(m.y) - .25) * 3.);
vec3 cRing = vec3(.98, .55, .12);
vec3 cSquare = vec3(.85, .25, .08);
vec3 cDiamond = vec3(.96, .80, .28);
col += cRing * smoothstep(.018, 0., abs(dRing))
+ cRing * exp(-abs(dRing) * 5.) * (.30 + hRing * .9);
col += cSquare * smoothstep(.018, 0., abs(dSquare))
+ cSquare * exp(-abs(dSquare) * 5.) * (.30 + hSquare * .9);
col += cDiamond * smoothstep(.018, 0., abs(dDiamond))
+ cDiamond * exp(-abs(dDiamond) * 5.) * (.30 + hDiamond * .9);
gl_FragColor = vec4(col, 1.);
}