Normal Map Conventions

There are two conventions for normal maps:

  • OpenGL (known as OpenGL-Style or Y+)

  • DirectX (known as DirectX-Style or Y-)

The difference between OpenGL style and DirectX style is the Y value (green channel) is flipped: OpenGL uses Y+ and DirectX uses Y-. This can cause shading on models to not look quite right if a material tries to use the OpenGL convention on a normal map designed for DirectX.

Luckily, JME supports both OpenGL and DirectX conventions by using a NormalType parameter in the Lighting and PBRLighting material definitions. The parameter can be set to either 1 (to use OpenGL) or -1 (to use DirectX). By default, JME uses the DirectX convention (NormalType is -1).

Using NormalType

If you’re using Lighting.j3md or PBRLighting.j3md for your materials, you can set the NormalType parameter to indicate which normal map convention materials should use on your normal maps.

Material mat = new Material(assetManager,
        "Common/MatDefs/Light/Lighting.j3md");
mat.setInt("NormalType", 1); //set the type to OpenGL
If you’re loading a model which already contains a material, you do not have to set the normal type on the material. Jme will do this automatically for you.

Which Convention are My Normal Maps?

There is no easy way to determine that. Sometimes the name of the texture itself might contain a clue determining its type. For example, "Material0_NormalMapY+.png" has Y+ in the name, so it is likely an OpenGL-type normal map. If the name doesn’t give any clue, the next step is to research the tool used to generate the normal map or look at where the normal map was downloaded from. Authors may indicate which normal map convention they used in their release notes.

Troubleshooting Normal Maps

If the shading on your models seems a little wrong when lit, that’s a good indicator that you’re using the wrong normal map convention. Changing the NormalType on your materials should fix it (if it does not, there is something else wrong).