Free · runs in your browser · nothing uploaded

Normal Map to Height Map Converter

Drop a normal map and get a grey height (displacement) map back: white is high, black is low. It runs in your browser, reads OpenGL and DirectX maps, keeps tileable textures tileable and saves a 16-bit PNG.

Loading the converter...

How to convert a normal map to a height map

  1. 1

    Drop your normal map

    A PNG, JPG or WebP tangent-space normal map (the blue-purple kind). Or press "Try a sample".

  2. 2

    Check the format

    Auto picks OpenGL or DirectX for you. If bumps come out as dents, choose the other one.

  3. 3

    Clean it up

    Use "Remove bowl / drift" if one side is darker, Blur for noisy JPGs, and Tileable for seamless textures.

  4. 4

    Download

    Save a 16-bit PNG for displacement (smooth, no stair steps) or an 8-bit PNG for anything else.

How it works, in plain words

Each pixel of a normal map is a direction: which way that bit of surface faces. Red is the left-right tilt, green the up-down tilt and blue how much it faces you.

A tilt is a slope, so the converter turns every pixel into two slopes, then finds the one surface whose slopes match all of them best. It does this for the whole image at once with a Fourier transform (the Frankot-Chellappa method), which is why even a 4096 px map takes only a few seconds.

A normal map only stores slopes, never absolute heights. Two flat areas at different heights look the same, so very sharp steps come out softer than the original. For bricks, tiles, rock, bark, fabric and sculpted detail the result is close to the real height.

Height map, normal map or displacement map?

Height mapGrey image, white = high. Used for parallax, for painting masks (dirt in the dents, wear on the edges), and as the source of other maps.
Normal mapBlue-purple image of surface directions. Fakes small bumps in the lighting on a flat surface without moving it. Cheapest; use it for fine detail.
Displacement mapThe same grey picture as a height map, but used to actually move the mesh. Needs a dense or subdivided mesh, and a 16-bit file avoids visible steps.

Rule of thumb: use the normal map for fine detail, the height map for parallax and masks, and displacement only where the silhouette must change.

Using the height map in your 3D app

Blender

Add an Image Texture node with the height map, set Color Space to Non-Color, connect it to a Displacement node (Midlevel 0.5) and that to the Material Output's Displacement. Subdivide the mesh for real displacement, or set the material to "Displacement and Bump".

Unity

Import the PNG and untick sRGB. Put it in the Lit material's Height Map slot for parallax; in HDRP pick a Displacement Mode (pixel, vertex or tessellation) to move the surface.

Unreal Engine

Import with sRGB off and a greyscale or displacement compression setting. Use it with a parallax node, or in the material's Displacement input on a mesh with tessellation enabled.

Substance 3D Painter

Import the PNG as a texture resource, add a Fill layer, turn on only its Height channel and drop the map there. Adjust the strength with the layer's height value.

Blender, Unity, Unreal Engine, Godot, 3ds Max and Substance 3D Painter are named only to describe compatibility; The3DAI is not affiliated with or endorsed by them.

Texture your 3D model with AI

Height and normal maps add detail to a texture you already have. To paint a whole model from a text prompt, with colour, normal and roughness maps, upload it to the AI 3D Texturing Studio. It uses credits; this converter does not.

Frequently Asked Questions

Yes, as a close estimate. A normal map stores the slope of every pixel, and the converter finds the surface that fits all those slopes. Relative heights come out right; the absolute depth is unknown, so set it with Strength or in your 3D app. Sharp steps between two flat areas come out softer, because flat areas carry no height information.
They differ only in the green channel, which is flipped. Auto checks which reading gives a surface that fits together and picks it. If the result looks wrong (bumps become dents or ridges smear sideways), choose the other format. Blender, Unity and Godot use OpenGL; Unreal Engine and 3ds Max use DirectX.
Small errors in a normal map (8-bit rounding, JPG noise, baking seams) add up into a slow slope across the whole image. Move "Remove bowl / drift" up until the large gradient is gone; low values keep big shapes, high values keep only fine detail.
Use the 16-bit PNG for displacement: it has 65,536 grey levels instead of 256, so a displaced surface stays smooth instead of showing terraces. The 8-bit PNG is fine for parallax, masks and painting.
Yes. Choose Edges: Tileable and the height map is solved as a repeating pattern, so its left and right (and top and bottom) edges meet without a seam. Leave it on Normal for maps that do not tile, such as baked character maps.
Usually nothing in the file: both are grey images where white is high. "Height map" is often used for parallax and texturing, "displacement map" when the image really moves the mesh. This tool makes one file that works as both.
No. The conversion runs in your browser, in a background thread, and the file never leaves your device.
Up to 4096 x 4096 pixels on a computer and 2048 on a phone. Larger images are scaled down to that size. Sizes that are not a power of two (like 1500 x 1000) work too.
Yes, with no sign-up and no watermark. If you also want to paint a whole 3D model from a text prompt, the AI 3D Texturing Studio does that with credits.