What a shader is
Purpose
A shader is one function that runs once per pixel, in parallel across the whole screen, with no knowledge of neighboring pixels or past frames.
Key insight
A painter paints the whole canvas in sequence, remembering what came before. The GPU doesn't work like that. It calls the same function for every pixel simultaneously. Each pixel knows only its own coordinate and the shared uniforms (like time). A pixel cannot see the pixel next to it.
When effects need neighbor information (blur, bloom, edge detection), that requires a second pass that samples the first pass's output as a texture. This is called multi-pass rendering — and it's how shaders get around their in-pixel blindness.
Break it
Drag pixel-size up to 64, then click pause time. Every "pixel" on screen becomes a single solid color, frozen. That one solid value is literally the output of one function call. Now click resume — every block changes together because they all share the time uniform.
Teaches: pixels are isolated in space but synchronized through uniforms. "Per-pixel parallel" is what a shader is.
Direct Claude
This lesson is conceptual — the language of art direction arrives in Lesson 2. Two useful phrases you'll pick up here:
uniform float u_pixelSize;
void main() {
// Where on screen is this pixel?
vec2 uv = gl_FragCoord.xy / u_resolution;
// Snap UV to a coarse grid (if pixel-size > 1).
// Every pixel in the same block reads the same snapped position.
float p = max(1.0, u_pixelSize);
vec2 snapped = floor(uv * u_resolution / p) * p / u_resolution;
// Compute a color from the snapped coordinate + time.
// Every pixel runs this same math independently.
vec3 col = 0.5 + 0.5 * cos(u_time + snapped.xyx * vec3(12.0, 9.0, 6.5) + vec3(0.0, 2.0, 4.0));
gl_FragColor = vec4(col, 1.0);
}