All Guides

What is a Normal Map? A 3D Artist's Plain-English Guide

By Voise · 3D artist since 200911 min read
Split-screen 3D render — a flat grey polygon plane on the left and the same plane rendered as detailed cobblestone via a normal map on the right
Same flat polygon, two lighting calculations. Left: no normal map. Right: tangent-space normal map applied.

A normal map is a texture that fakes 3D surface detail by encoding which direction every pixel "faces" into red, green, and blue. The renderer reads those directions, lights the surface as if the detail were really there, and a flat triangle suddenly looks like cobblestone or wood grain — no extra polygons, no extra render cost, no second mortgage on your GPU.

TL;DR

  • A normal map is an RGB texture where the colours mean directions, not colours.
  • It lights a flat surface as if it had thousands of bumps you never modelled.
  • Nine out of ten "broken" normal maps are a wrong green channel.
  • You can bake one, generate one from a photo, or have an AI make one for you.
  • Resolution should match your albedo. Going higher is just heat.

Right. I've been making PBR textures since 2009 — when normal maps still had "NMAP" written on them in big letters because half the engines didn't know what to do with the file otherwise. Let me explain what they actually are, why they're purple, and the one channel that ruins everyone's afternoon.

Why we use normal maps in the first place

Real surfaces have detail at every scale. Wood has grain. Concrete has pits. Metal has fine scratches you'd never see unless you put your eye on it. Modelling every one of those as actual geometry is possible — it's also a great way to ship a game that runs at three frames per second on a cooled engine block.

A normal map cheats. Instead of moving any vertices, it tells the lighting calculation that the surface points in a different direction at every pixel. Light hits a flat plane and bounces as if it were a brick wall, because the maths thinks it's a brick wall. Same number of triangles. Same memory cost as a regular image.

The savings are obscene. A modern game character might use about 80,000 triangles. The same character sculpted at "all detail in geometry" quality would need somewhere north of 20 million. Toy Story 1's Buzz Lightyear had fewer polygons than a modern eyelash. We've come a long way, mostly by lying about it.

How a normal map actually works

Every pixel of a normal map stores three numbers. Not a colour — a direction vector. The red channel is the X component, the green channel is Y, the blue channel is Z. Each value runs from -1 to 1, but image files only store 0 to 1, so the renderer doubles it and subtracts one to get the real range. Maths.

When the lighting calculation needs to know which way the surface points at a given pixel, it doesn't use the geometry's flat normal. It reads the colour out of the normal map, decodes it back into a direction, and uses that. The same flat triangle now has a different surface normal at every texel, and light bounces accordingly.

That's the whole trick. The hard part is everything around it — how the directions are stored (object space or tangent space), how the engine reads them, and which axis it considers "up". We're about to get into all of that. Refill your coffee. I'll wait.

Why are normal maps purple?

Look at any normal map and you'll see the same washed-out lavender colour everywhere it isn't doing anything interesting. There's a reason: that colour is the encoding of a vector pointing straight out of the surface.

A vector pointing "forward" in tangent space is (0, 0, 1). Convert that to image colour and you get (0.5, 0.5, 1.0) — half red, half green, full blue. Your monitor renders that as light purple. Anywhere on the map that's flat-and-boring is encoded as "point forward, no change", and that's the colour you get.

Tangent-space normal map texture for a wooden plank — predominantly purple-blue with subtle green and red variations along the wood grain
A tangent-space normal map for an oak plank. The purple wash is "point forward". The colour shifts are the wood grain.

If your normal map is mostly green, or mostly red, or mostly anything other than purple, something has gone wrong. (Either the map was painted in the wrong colour space, or it's an object-space map — which we're about to get to, fair warning.)

Tangent space vs object space

Two flavours of normal map. Both common. Different problems.

Tangent-space normal maps store directions relative to the surface itself. The map doesn't care whether your model is a wall, a sphere, or a barrel — the directions adapt because the renderer transforms them at runtime using the surface's tangent and bitangent vectors. This is what you want 99% of the time. It's also what makes the map look mostly purple.

Object-space normal maps store directions in the model's local coordinate space. They're technically slightly faster to sample and look like a rainbow ham — every colour, no purple wash. The downside is they only work for a single specific model. Bend the model, animate it, or instance it across a scene, and the map breaks. Use object-space for static, unique props if you really want to. Otherwise use tangent space and don't think about it again.

Side-by-side comparison of tangent-space (purple) and object-space (rainbow) normal maps of the same stylised 3D rock
Same model, two encodings. Tangent space (left) reuses anywhere. Object space (right) is glued to the one model it was baked for.

Normal map vs bump map vs height map

Three different things, often confused, including by my junior Jake, who I've told fourteen times this month. He still mixes them up. Fair enough. Here they are:

  • Bump map — a single-channel greyscale image. Lighter pixels look raised, darker pixels look recessed. The renderer infers direction from the slope of the brightness. Cheap, lossy, mostly obsolete except as a quick stand-in.
  • Normal map — an RGB image where every pixel directly stores a 3D direction vector. The renderer doesn't infer anything; it reads the direction off the map. Much more accurate. The modern default.
  • Height map (displacement map) — also a greyscale image, but it's used to actually move the geometry at render time, not just fake lighting. Correct silhouettes, correct self-shadowing, real depth. Expensive. Worth it for cobblestone and bark where the shape matters.
Bump map, normal map, and height map of the same brick wall, side by side as a triptych for comparison
Bump (left, greyscale heights), normal (centre, RGB directions), height/displacement (right, real geometry). Same wall, three jobs.

Rule of thumb: normal map for fine detail, height/displacement when you can see the silhouette of the bumps, bump map only when you're writing a 1998 retrospective.

OpenGL vs DirectX: the flipped green channel

Now we're at the part that makes 3D artists drink. Two of the major rendering conventions disagree on which way the Y axis points in a normal map. Specifically:

  • OpenGL convention — Y is up. Green channel up = surface bump pointing up. Blender, Substance Painter, glTF, and Three.js default to this.
  • DirectX convention — Y is down. Green channel up = surface bump pointing down. Unreal Engine and many older Unity setups expect this.
Same brick wall rendered with OpenGL convention (bricks raised correctly) and DirectX convention (bricks dented inward) — the green-channel flip in action
Same brick wall, same light. Left lights as OpenGL expects (bricks raised). Right lights as DirectX expects with the OpenGL map (bricks dented). One green-channel flip away from each other.

Same map, opposite assumption. Plug an OpenGL-baked normal map into Unreal Engine without flipping the green channel and every bump becomes a dent. Every seam down a barrel suddenly looks lit from the inside — which is technically a feature if you were planning on being a lighthouse.

Nine out of ten "broken-looking" normal maps in Unity are this exact problem. The fix: either flip the green channel before export (a tickbox in Substance Painter or a one-line channel invert in Photoshop), or tell the engine to do it on import. Unity 6 has a checkbox. Unreal has a node. Godot reads it however you tell it. Don't fight it; just set it.

Honest numbers: I've lost half a day to this exact bug at least three times in my career, and I knew it was the bug each time. The mind is a wonderful thing.

How to make a normal map (three methods)

There are three real ways to make a normal map in 2026. They serve different jobs.

1. Bake from a high-poly mesh

The classic. Sculpt every detail you want — every pore, every panel line, every chip — on a high-poly model in ZBrush, Blender, or your tool of choice. Then bake the surface direction onto the UVs of a low-poly version using Marmoset Toolbag, Substance Painter, xNormal, or Blender's baking pipeline.

Pros: highest fidelity, full artist control, exact match to the silhouette you sculpted. Cons: time. A hero prop can be a full day's sculpting plus a couple hours of bake fiddling. Good for one-off heroes. Slow for filling a level.

High-poly rock with dense wireframe next to the same rock as a low-poly model with a baked normal map applied — both visually identical
Left: five million triangles. Right: five thousand triangles plus a normal map. Same render. One fits in a game.

2. Generate from a photo or height map

Got a photo of a surface? A greyscale height map? A scan? You can convert it into a normal map using something like NormalMap Online, AwesomeBump, Substance Designer's height-to-normal node, or the built-in Photoshop NVIDIA filter. The tool reads the luminance, treats it as height, and approximates direction.

Pros: fast, free, works for rough/matte surfaces like concrete, stone, and dirt. Cons: it's an approximation. Shiny surfaces, transparent surfaces, and anything with baked-in highlights confuse the algorithm. The result usually needs a clean-up pass.

3. Generate from a text prompt with AI

New flavour. Describe the surface in plain language — "weathered copper roof tile", "polished oak floorboards", "sci-fi panel with rivets" — and an AI model produces a complete PBR set: albedo, normal, roughness, AO, metalness. The normal map comes out coherent with the rest of the maps, which is the bit photo-to-normal tools usually get wrong.

Pros: seconds, not hours. The maps are designed together, so the normal map agrees with the albedo about where the bumps are. A good tool lets you pick OpenGL or DirectX on export, so the engine convention is handled for you. Cons: AI-generated maps still need a human to fix the corners. The model does the heavy lifting; I do the cleanup.

Five PBR texture maps generated from a single text prompt for a weathered oak plank — albedo, normal, roughness, ambient occlusion, and metalness
One text prompt, five PBR maps. Albedo, normal, roughness, AO, metalness — designed together so the bumps agree with the colour.

If you want to try this approach, CraftPBR generates the full PBR set from a text prompt with no sign-up needed. Free up to ten generations a day. That's genuinely enough to finish a small game.

Generate a normal map in 30 seconds

Describe any surface. CraftPBR returns the full PBR set — albedo, normal, roughness, AO, metalness — ready for Unity, Unreal, Blender, Godot, or Three.js.

Try It Free

When normal maps stop helping

Normal maps are not a silver bullet. They fake lighting, not geometry. Here's when they stop being useful:

  • At grazing angles. Look down the length of a cobblestone wall and the bumps flatten back out. The silhouette is still the silhouette of a flat polygon. That's when you need displacement.
  • When the "detail" should cast a shadow on itself. A deep groove should darken its own neighbours. Normal maps don't do that; you'd need a separate AO bake or parallax occlusion.
  • At very low resolution. A 256×256 normal map on a hero prop looks like blurry plasticine. Match your texel density to the rest of the material.

Rule of thumb: if you can clearly see the bumps in silhouette, you need real geometry or displacement. If you'd only ever notice the bumps because of how light catches them, you need a normal map. Pick the cheap option whenever the cheap option works.

Straight answers

The questions I get asked at the pub, with one-paragraph answers.

What is a normal map used for?

Faking surface detail — pores, scratches, grain, panel lines — without adding any geometry. A flat triangle can look like cobblestone for the price of one texture lookup.

What is the difference between a normal map and a bump map?

A bump map is greyscale; the renderer guesses direction from brightness. A normal map is RGB and stores the direction directly. Normal maps are more accurate, especially at grazing angles. Use normal maps unless you're writing a 1998 retrospective.

Why are normal maps purple?

Because (0, 0, 1) — "point straight out" — encodes to RGB (0.5, 0.5, 1.0), which is light purple. Anywhere the surface is flat-and-boring is purple. Anywhere it isn't purple, there's detail.

Can I make a normal map from a photo?

Yes, but it's approximate. Tools like NormalMap Online, AwesomeBump, or AI generators infer direction from photo luminance. Works for rough surfaces, less well for shiny or transparent ones. AI tools that generate the matching albedo and roughness at the same time give the most usable result.

What is the difference between OpenGL and DirectX normal maps?

The green channel. OpenGL expects Y up; DirectX expects Y down. Same map, opposite convention. Wrong setting means every bump becomes a dent. Blender and Substance Painter default to OpenGL; Unreal Engine expects DirectX; Unity 6 lets you pick.

Do AI-generated normal maps work in Unity and Unreal?

Yes — provided the tool exports the right Y-axis convention for your engine. Good generators let you pick OpenGL or DirectX on export. The maps themselves are standard RGB textures and import like any other PBR map.

What resolution should my normal map be?

Match your albedo. 2K (2048×2048) is the modern baseline for PC/console. 4K for hero assets the camera gets close to. 1K for Switch and mobile. Going higher than your albedo is just heat.

If you want the full picture of how normal maps fit into a PBR material, read my guide to PBR materials — it covers all the maps that travel together (albedo, roughness, AO, metalness) and how they interact. If you're ready to skip the bake and let the model do the heavy lifting, the AI workflow guide walks through prompt-to-export in under a minute. And if you just want to grab some free normal maps to drop into a scene right now, the community library has CC0 PBR sets ready to download.

Further reading

Cobblestone PBR material rendered on a sphere with golden-hour lighting — normal maps in production
Flat geometry. Normal map. Decent lighting. That's the whole trick.

That's normal maps. The model does the heavy lifting; you do the cleanup. Go make something. And if your bumps look like dents, check the green channel before you blame the engine.

↑ Back to top