Skip to content
Normalforge

Normal maps and PBR textures in your browser

Normal Map Checker

Check a normal map for vectors that are not unit length, pixels that point into the surface, and a likely green-channel mix-up.

Free · runs in your browser · nothing is uploaded

Open on Normalforge

This embed was switched off for this website. Open on Normalforge

Add this tool to your siteFree embed code, no sign-up. Keep the credit link.

Embed this tool

Copy this code into your website, blog or class page. The tool runs inside your page.

Optional settings, added to the address after embed=1: &accent=0f6b5c (colour, 3 or 6 hex digits). Other parameters are ignored.

Please keep the credit link below the tool.

A normal map checker tests whether every pixel of a normal map still holds a valid direction: a vector of length 1 that points out of the surface. This one decodes each pixel, measures its length, counts the pixels that are too long, too short, pointing inward or empty, and paints an error map so you can see where the problems sit. It also guesses whether the map is OpenGL or DirectX style and gives you a fixed copy rescaled to unit length. Use it on a map that shades oddly in your engine, after resizing or editing a map in an image editor, or before you ship textures from a library you did not make.

It reads 8 and 16-bit PNG and TGA files without loss, so what you see is what the file holds.

Normal map checker example

How to use the Normal Map Checker

  1. Drop the normal map on the tool, paste it or press Choose image. Try a sample loads a map whose top quarter has been squashed on purpose.
  2. Read the stats line: Mean length, Min length, Max length, Out of tolerance, Pointing inward, Flat, Convention guess and Confidence.
  3. Open the Error map view to see where the faulty pixels are.
  4. Adjust Length tolerance (0.005 to 0.1, default 0.02) to decide how far from 1 a length may be before it counts as wrong.
  5. Compare the original with the Fixed normal map view, then check it in the 3D preview.
  6. Press Download Error map, Download Fixed normal map or Download all (ZIP).

Rounding to 8-bit moves lengths only a little: a clean map from the generator, saved as 8-bit, ranges from 0.994 to 1.006, well inside the default tolerance. Values outside it point to real damage.

Start with the stats rather than the picture. If Out of tolerance is close to 0 % and Pointing inward is 0 %, the map is technically sound and any shading problem lies elsewhere, usually the convention or the import settings. High numbers send you to the Error map to find the area.

The fixed copy keeps the size (up to 16384 px) and the convention of the original, so it can replace the file directly.

How do I tell if a normal map is broken?

Decode each pixel to a vector n = 2v − 1 and measure its length. A valid tangent-space normal has length 1 and a positive Z (blue above mid grey). Lengths well below 1, Z below zero or empty pixels all render wrong: too dark, too flat, or lit from inside the surface.

The error map uses these colours:

ColourMeaning
greylength within the tolerance of 1
redlonger than 1 (brighter = further off, full colour at 0.25)
blueshorter than 1 (brighter = further off)
yellowpointing into the surface (z < 0)
blackempty vector (length under 0.01)

On the built-in sample the checker reports a mean length of 0.909, a minimum of 0.6 and 25 % of pixels out of tolerance, all in the squashed top quarter, with a convention guess of OpenGL at confidence 0.97.

Why are the vectors in my normal map too short?

Short vectors come from treating a normal map like a photo. Averaging two unit vectors that point in different directions gives a shorter one, so any operation that blends neighbouring pixels shortens them:

  1. resizing or blurring without renormalizing afterwards;
  2. mipmaps built without renormalization;
  3. JPEG compression and painting or cloning on the map;
  4. colour management that converted the file as sRGB.

The Fixed normal map rescales every vector back to length 1 and replaces empty or broken pixels with the flat normal (128, 128, 255). It fixes lengths only: a map that points the wrong way stays wrong.

What do the numbers mean in practice?

StatHealthy mapSuspicious
Mean lengthabout 1.00clearly below 1, e.g. 0.9
Out of tolerancenear 0 %several percent
Pointing inward0 %anything above 0 %
Flatdepends on the texture100 % means no relief at all

A large Flat share is normal for a texture with smooth areas; it only signals trouble when the map should show detail everywhere.

Pointing-inward pixels deserve special attention. A tangent-space normal should never face into the surface, so any yellow in the error map means the blue channel was damaged, the map was inverted as a whole, or it is not a tangent-space map at all (object-space maps use the full colour range).

Questions and answers

What does the error map show?

Where the problems are: grey is fine, red too long, blue too short, yellow pointing inward and black empty.

Does the checker fix the map?

It rescales every vector to unit length in the Fixed normal map output. Wrong conventions, seams and inverted details need the converter or a new bake.

How does the convention guess work?

A map baked from a height field has slopes that fit together with no curl. The test reads green both ways and reports the reading that fits, with a confidence from 0 to 1, or unknown when the relief is too weak.

What does Length tolerance change?

Only which pixels count as wrong in the stats and the error map. The fixed map is the same at any tolerance.

Can I check a map that has an alpha channel?

Yes. Alpha is ignored; only red, green and blue are decoded.

Which file types can I check?

Any image the tool reads: PNG in 8 or 16-bit, TGA, BMP, JPG, WebP and EXR. Prefer PNG or TGA, because JPEG compression itself creates length errors.

Why does the checker show errors along a seam?

Often the map was painted or cloned there, or two bakes were joined. The error map shows the line; rebake it or let the fixed copy restore unit length.