OpenGL vs DirectX Normal Maps: Which One Your Engine Needs

There are two normal map conventions, and they differ in exactly one thing: the direction of the green channel. Using the wrong one makes bumps look like dents.

Updated

The only difference is green

A tangent-space normal map stores a direction in each pixel: red is left to right, green is up and down, blue points out of the surface. The two conventions disagree on which way is "up" for green. OpenGL-style maps are Y+, so a surface facing the top of the texture is bright green. DirectX-style maps are Y−, so the same surface is dark green. Red and blue are identical.

Which format each engine expects

  • OpenGL (Y+): Unity, Godot, Blender, Maya, the glTF format, three.js.
  • DirectX (Y−): Unreal Engine, 3ds Max, Source.
  • Substance Painter and Designer can export either; check the export preset.

How to tell which one you have

Find a clearly raised detail, such as a rivet or a brick. In an OpenGL map its top edge is greener (lighter in the green channel) and its bottom edge is darker. In a DirectX map it is the other way round. In the engine, the symptom of a wrong map is lighting that looks inverted vertically: with a light from above, raised details are lit on their lower edge.

Converting between the two

Invert the green channel and nothing else. In an image editor, select the green channel and invert it. Most engines can also do it on import: Unreal Engine has a Flip Green Channel checkbox in the texture settings, and Godot has an equivalent option for normal maps in the import dock.

If you are generating the normal map from a height map anyway, choose the right convention when you generate it and there is nothing to convert.

Other reasons a normal map looks wrong

  • It was imported as a colour texture. Normal maps must be linear: set the texture type to Normal map in Unity, or Compression Settings to Normalmap in Unreal.
  • The height was inverted when it was generated, so the whole relief is inside out rather than just flipped vertically.
  • The mesh has no tangents, or its tangents were computed differently from the tool that baked the map.

Next: pack the other maps

Once the normal map is right, the remaining grayscale maps — metallic, occlusion, roughness — go into one packed texture.

Tools for this guide

All tools →

More guides

All guides →