Normal map

A purple-blue texture that fakes bumps and dents by lying about which way the surface faces, so light reacts as if detail were there.

fake bumpinessdetail without more polygonsthat purple texturethe blue texture that makes it look bumpywhy do the bumps look invertednormalmaptangent space normal mapfake surface detail texture

See it

Live demo coming soon

What it is

A normal map stores a direction in every pixel: red, green, and blue encode the X, Y, Z of the surface's facing angle instead of a color. The shader uses that faked angle when it calculates local lighting, so a perfectly flat triangle picks up highlights and shading as if it had pores, stitching, grout lines, or screw heads. The lavender-blue color is just what 'pointing straight out' looks like when encoded (128, 128, 255). Grayscale bump and height maps are the older ancestor: the shader derives a perturbed normal from the height field, so those respond to a moving light too. Normal maps store the directions outright, which is cheaper to sample and lets you encode richer detail (sharp bevels, directional grain) than one height channel can express.

The standard workflow is baking: sculpt a multi-million-triangle version in ZBrush or Blender, then transfer its detail onto a low-poly mesh as a normal map. You keep the silhouette cheap and the surface expensive-looking. This is how nearly every game and web 3D asset gets its detail budget.

Gotcha: it is a lighting lie, not geometry. The silhouette stays perfectly flat, and at grazing angles the illusion collapses because bumps do not occlude each other or cast shadows. Real relief needs a displacement or parallax map. Two more traps: normal maps must be loaded as linear (non-color) data or the lighting goes subtly wrong, and the green channel convention differs between OpenGL and DirectX, so a map that looks inverted (dents where bumps should be) usually just needs its green channel flipped.

Ask AI for it

Add a tangent-space normal map to this material to fake fine surface detail (leather grain and stitching) without adding geometry: load it as linear/non-color data, not sRGB, set normalScale around 0.8, and tile it against the existing UVs. In three.js use MeshStandardMaterial with normalMap plus a roughness map so the bumps also break up the reflections. If the detail looks inverted, flip the green channel (OpenGL vs DirectX convention). Keep the mesh low-poly: the silhouette should stay unchanged.

You might have meant

displacement maptextureuv mapping uv unwrappingbakingsurface normals backface culling

Go deeper