← NACK3D
RU EN
GUIDES
Guide · PBR workflow · 7 min read

How to Make a Normal Map from a Photo: 4 Working Methods

A normal map is a texture that encodes surface relief into pixel color: flat geometry starts looking detailed without extra polygons. Below are four ways to get one from an ordinary photograph — from classic plugins to on-device Android scanning.

Example of a normal map generated from a photo
Normal map: purple background = flat plane, color offsets = relief

Method 1. Photoshop + NVIDIA Texture Tools plugin

  1. Open the photo: File → Open.
  2. Desaturate: Image → Adjustments → Desaturate (Ctrl+Shift+U). Brightness becomes “height”: lighter = higher.
  3. Boost contrast: Image → Adjustments → Levels (Ctrl+L) so the relief reads clearly.
  4. Install the free NVIDIA Texture Tools Exporter plugin.
  5. Filter → NVIDIA Texture Tools → Normal Map, tune the relief strength.
  6. Save as PNG.
Limitation: height is taken from brightness. On patterned textures (wood with growth rings, printed fabric) the pattern leaks into the relief as an artifact.

Method 2. GIMP + NormalMap plugin (free)

  1. Install GIMP and the NormalMap plugin (Windows / Linux / macOS).
  2. Colors → Desaturate.
  3. Filters → Map → Normalmap.
  4. Tune parameters (strength, wrap, height source) → OK.
  5. File → Export As… → PNG.
Same plus and minus: relief is “guessed” from brightness, not measured.

Method 3. Online normal map generators

Services like NormalMap-Online: upload a photo → tweak sliders → download PNG. Nothing to install, but three “buts”: the photo goes to a third-party server (privacy), the output is 8-bit, and the generator gives no other maps (albedo, roughness, height).

Method 4. Photometric stereo on Android (real relief)

The first three methods assume relief from brightness. The fourth measures it: the Shape-from-Shading method captures a series of frames under different lighting (flash + screen) and computes how the surface reflects light at varying angles. The result is a true micro-relief map, not an imitation.

In NACK3D it looks like this:

  1. Open the app and point the camera at a surface.
  2. Tap CAPTURE — the phone shoots the series with different light on its own.
  3. In ~7 seconds you get 16-bit Normal and Height plus Albedo, Roughness, AO and Specular — all processed on-device, no cloud.
  4. Export to Unity, Unreal or as separate files.
Before and after: a surface photo and the reconstructed relief
Left — the source photo, right — the same area with reconstructed relief

Method comparison

MethodCostRelief sourceBit depthOther mapsPrivacy
Photoshop + pluginAdobe subscriptionbrightness8nonelocal
GIMP + NormalMapfreebrightness8nonelocal
Online generatorfreebrightness8nonephoto on server
NACK3D (SfS)7 days freelight (photometric stereo)up to 166 mapslocal, offline

Frequently asked questions

Why is a normal map purple?

The RGB channels encode the normal’s offset along the X, Y, Z axes. A flat patch is the vector (0, 0, 1), which in color gives (128, 128, 255) — that lilac-blue tint. Relief offsets shift the color toward red and green.

OpenGL or DirectX: what’s the difference?

In OpenGL the green channel points up (Y+), in DirectX — down (Y−). The wrong choice flips the relief inside out. Unity uses OpenGL, Unreal uses DirectX; NACK3D has a Flip Y toggle and ready-made packs for each engine.

What bit depth do I need?

8 bits is enough for game materials at mid distance. For close-ups, displacement and cinematics take 16 bits — otherwise smooth slopes show banding steps.

Can I make a normal map from a single photo?

Methods 1–3 work with one file, but the relief will be conditional. Photometric stereo needs a series of frames under different light — the phone shoots it itself in a second, so the result is closer to a real scan.

Try Method 4 in practice

NACK3D — a texture scanner for Android: normal, depth and a full PBR set from a single shot, processed on-device. The first 7 days are free.

Get it on Google Play ↗