Shader
A tiny program that runs on the GPU for one pipeline stage: per vertex to place points, per fragment to pick a color.
See it
What it is
A shader is a small program that runs on the GPU for one stage of the rendering pipeline, in parallel, across a lot of invocations. The vertex shader stage runs once per vertex and decides where that point of the mesh lands on screen. The fragment shader stage runs once per generated fragment and decides what color that fragment contributes. Written in GLSL for WebGL or WGSL for WebGPU. Invocations are generally independent: one fragment cannot inspect the fragment next door or walk the rest of the scene. It can absolutely sample neighboring texels out of a texture, read buffers, and loop over an array of lights, but each invocation takes its own inputs and returns its own answer, which is exactly why a GPU can run millions of them at once.
You write one when the built-in materials cannot do the thing: liquid distortion, animated gradients, dissolve and glitch transitions, grass bending in wind, raymarched blobs, toon bands with a hard specular step. In practice most web work is a hybrid, patching a few lines of custom code into a standard PBR material rather than rewriting lighting from scratch.
Gotcha: the fragment stage runs per generated fragment per frame, and that is more than once per pixel wherever triangles overlap or multisampling is on, so a full-screen effect at retina resolution on a phone is millions of executions sixty times a second. Branching, big loops, and stacked texture reads get expensive fast. The other classic trap: shader compilation happens at runtime and can freeze the first frame, so warm up your materials before the user sees the scene.
Ask AI for it
Write a GLSL fragment shader for a full-screen plane that animates a two-color gradient with flowing organic distortion: use simplex noise driven by uTime and the UV coordinates, mix between two uniform colors with smoothstep, and add a soft grain by mixing in a cheap hash-based noise at 4% opacity. Expose uTime, uResolution, uColorA, and uColorB as uniforms. Keep it branch-free and under one texture read per fragment so it stays smooth on mobile.