Shader Lab
03.The primitives tour

The primitives tour

Arc 1 · Mental Model · Lesson 3 of 35
coordinate signal color

Purpose

See the handful of mathematical building blocks that compose virtually every shader — eight tiny demos, one per primitive, so you recognize them on sight.

step(edge, x)
Hard threshold. Below edge, 0. Above, 1.
edge 0.50
smoothstep(a, b, x)
Soft threshold. Same as step but the edge is a gradient.
softness 0.10
mix(a, b, t)
Linear blend from a (left) to b (right). Line marks the current t.
t 0.50
dot(a, b)
Vector alignment. A lit sphere: shade is dot(normal, light).
angle 0.80
length(v)
Radial distance from a point. Concentric rings around the center.
center 0.00
fract(x)
Drops the integer part. Tiling and repetition come from this.
repeat 4.0
sin(x)
The universal wave. Everything oscillating is some flavor of this.
freq 12
noise(p)
Controlled randomness. Smooth, deterministic, tunable by scale.
scale 6.0

Key insight

About a dozen operations cover 90% of what real shaders do. Every effect later in the lab is some combination of these. They're not algebra — they're verbs.

step is "is x past this line?" smoothstep is the same question with a soft answer. mix is "blend two things." dot is "how aligned are two directions?" length is "how far from origin?" fract is "tile everything." sin is "make it wave." noise is "controlled randomness."

Once each of these has a face, reading shaders stops being decoding and becomes recognition.

Break it

1. Put the step and smoothstep demos side-by-side. Pull smoothstep's softness to 0. They look identical. Teaches: smoothstep is step when softness is zero — they're the same tool in different modes.

2. In the dot demo, rotate the angle past 90° (slider past ±1.5). The sphere goes dark on the back. Internally, dot is going negative — we clamp it to zero, which is why surfaces facing away from a light are black in Lambert shading (Lesson 17).

3. In the fract demo, set repeat to a non-integer like 3.7. The last tile looks crooked — a partial repeat. Teaches: tiling cleanly requires integer multiples.

Direct Claude

Each primitive now has a name you can use directly in a brief. Some common requests:

"hard edge at this value" step(edge, signal) "soften the transition" swap step for smoothstep, widen softness "blend these two looks" mix(a, b, t) with t from a slider or signal "light the surface" dot(normal, light) — foundation of lighting "rings around a point" length(uv - center) "tile this N times" fract(uv * N) "make it oscillate" sin(x * freq + time) "add natural variation" noise(p) — not white noise, smooth/gradient noise
Meta-phrase you gain here: the primitive names themselves. "Use a smoothstep between 0.3 and 0.7 on the signal" is a specific, executable brief. "Make it smoother" is not.
Combines with: every subsequent lesson — they're all recipes made from these primitives.