Normal Map Format: DirectX vs OpenGL
What is Normal Map Format
A normal map stores surface normal information, used to simulate high-resolution details on low-poly models. Due to differences in coordinate systems between graphics APIs, normal maps are divided into two main formats: DirectX and OpenGL. The key difference lies in the orientation of the green channel (corresponding to the Y-axis or bi-tangent direction in tangent space) in the normal map.
- **DirectX format**: Typically uses +Y direction up, meaning the green channel in the normal map represents normals pointing upward.
- **OpenGL format**: Typically uses +Y direction down, meaning the green channel represents normals pointing downward.
This difference arises from different conventions in texture coordinates and projection matrices between the two APIs. Using the wrong format can cause lighting to appear reversed or bump effects to be incorrect.
How to Distinguish DirectX and OpenGL Normal Maps
You can roughly tell by observing the colors of the normal map:
- **DirectX**: Convex parts (such as brick edges) usually appear green or yellow-green because the green channel value is high.
- **OpenGL**: Convex parts may appear purple or blue-purple because the green channel value is low, while red and blue channels are unaffected.
A more accurate method is to check flat areas facing the camera: in DirectX, such areas are typically light purple (128,128,255); in OpenGL, they may also be (128,128,255), because a flat normal in tangent space is (0,0,1), mapping to color (128,128,255) (R=0.5, G=0.5, B=1.0). The green channel value of 0.5 corresponds to Y component 0, so direction does not affect flat colors. For non-flat areas, you can judge by known bump directions.
Many DCC tools (such as Substance Painter) allow you to choose the export format.
Why Are There Two Formats
DirectX and OpenGL have differences in texture coordinate systems: DirectX's texture coordinate origin is at the top-left, while OpenGL's is at the bottom-left. This causes the V-axis (affecting the green channel) in normal maps to be reversed. Additionally, the construction of tangent space may also differ. Therefore, normal maps generated for different APIs need to be adapted.
In actual development, engines usually handle this difference. For example, Unity defaults to OpenGL style (but can be switched in import settings), while Unreal Engine uses DirectX style. Care is needed when exchanging assets across engines.
How to Convert Normal Map Formats
Converting normal map formats is very simple: just flip the green channel. That is, G' = 1 - G (in normalized values) or G' = 255 - G (in 8-bit color). This can be done in image editing software like Photoshop through channel operations, or via scripts for batch processing.
Many tools provide automatic conversion, for example:
- **xNormal**: Offers format selection when exporting.
- **Substance Designer/Painter**: In export settings, you can choose DirectX or OpenGL.
- **Blender**: When importing normal maps, you can choose color space and flip the green channel.
Handling in Game Engines
- **Unity**: When importing a normal map, in the texture import settings, if the format does not match project settings, you can check "Flip Green Channel" to flip it. By default, Unity expects OpenGL style but can auto-handle based on platform.
- **Unreal Engine**: Uses DirectX style, but usually automatically detects and provides flip options when importing normal maps.
- **Custom engines**: Ensure shaders decode normal maps correctly and consider API differences.
Summary
Understanding the differences between DirectX and OpenGL normal map formats is crucial to avoid rendering errors. By correctly identifying and converting formats, you can ensure normal maps display properly on the target platform.
FAQ
What is the difference between DirectX and OpenGL normal maps?
The main difference is the green channel: DirectX normal maps have the green channel pointing up (Y+), while OpenGL has it pointing down (Y-). This can cause bump effects to appear reversed when used on the wrong platform.
How to tell if a normal map is DirectX or OpenGL?
Observe convex areas: if they appear yellow-green, it's likely DirectX; if blue-purple, it's likely OpenGL. A more reliable method is to use tools or test renders.
How to convert a DirectX normal map to OpenGL?
Flip the green channel. In image editing software, invert the green channel (e.g., in Photoshop, Ctrl+I on the green channel). You can also use engine import options to auto-flip.
Which normal map format does Unity use?
Unity defaults to OpenGL style, but when importing normal maps, it can auto-handle based on platform. If normal direction appears wrong, you can flip the green channel in import settings.
What happens if the normal map format is wrong?
Lighting direction may be reversed, convex parts become concave, and surface details invert. For example, brick gaps may bulge instead of recess.