A face only has one flat normal — the direction it points — but lighting is computed per pixel, not per face. A normal map is a texture that encodes a different normal for every pixel in its RGB channels: R holds the X tilt, G the Y tilt, B the Z tilt, which is why a typical normal map looks like a soft lavender-blue haze.
When the renderer shades the surface, it reads a normal from this texture for every pixel and uses that in the lighting math instead of the face’s flat one. The actual geometry stays flat, but light appears to flow across bumps that aren’t really there — and, like bump and displacement maps, the silhouette never changes; that’s the shared limitation.
In Blender, Maya, or C4D the standard workflow is “baking” a high-poly sculpt down onto a low-poly mesh to produce this normal map (see texture-baking). This demo skips that pipeline and builds a small height field of procedural bumps directly, deriving normals from it and lighting them with a moving light.
When to use
Use it in real-time games or web 3D to add surface detail — wrinkles, rivets, fabric weave — without spending more polygons.