The 3D Handbook
Key term

Tangent space and MikkTSpace

The per-vertex frame a normal map is read in; why the baker and engine must calculate it identically (MikkTSpace), what a synced workflow is, and which engines expect OpenGL (Y+) or DirectX (Y−) green channels.

bakingnormal-mapsshading

Tangent space is a small coordinate frame at every point of a mesh, made of the surface normal (N), a tangent (T) that follows the U direction of the UVs, and a bitangent (B) that follows V. A tangent-space normal map stores directions relative to this frame, which is why the same map works on a mesh that moves, bends or is rotated. Blender calls tangent space "the default, and the right choice in most cases" for baked normal maps (Blender Manual: Render Baking).

Left, a flat quad with a point on it and three arrows, N pointing up labelled normal, T along the surface labelled follows U, and B along the surface labelled follows V. Right, two bevelled squares showing the green channel of the same raised shape. In the OpenGL Y plus square the top bevel is bright and the bottom dark; in the DirectX Y minus square the top bevel is dark and the bottom bright.
Left, the tangent frame a normal map is read in. Right, the same bump in the two green-channel conventions; only the green channel differs.Diagram by the handbook author
A lavender normal map texture with outlines of bolts, grooves and bevelled edges.
The tangent-space normal map baked for the box in the high-to-low render, 1024 × 1024, on a Smart UV Project layout. Flat areas are exactly RGB 128, 128, 255; slopes shift the colour towards red or green depending on their direction.Rendered in Blender 5.2 (Cycles) by the handbook author

#Matching tangent space in baker and engine

The baker writes colours by comparing the high poly against the low poly's tangent frame; the engine reads them back with its own tangent frame. If the two frames differ even slightly, the shading is wrong: soft gradients, seams or X-shaped smudges. MikkTSpace's source header states the requirement plainly: "the normal map sampler must use the exact inverse of the pixel shader transformation" (GitHub: mikktspace.h).

Tangent frames depend on the mesh's normals, UVs and triangulation. Marmoset calls X-shaped errors "a type of tangent space mismatch, as variance in the edge direction can cause the tangent basis to differ" (Marmoset Toolbag documentation: Baking Tips & Tricks). This is one reason to triangulate before baking (Substance 3D Bakers documentation: Triangulating before baking).

#MikkTSpace

MikkTSpace is a tangent-space algorithm written by Morten S. Mikkelsen in 2011, "designed to consistently generate the same tangent spaces, for a given mesh, in any tool in which it is used" (GitHub: mikktspace.h). It became the common standard for game art:

Even within MikkTSpace there are small variants. Substance Painter's per-fragment option is set off for xNormal and Unity 5.3+, and on for Unreal Engine 4, Blender and Unity HDRP (Substance 3D Bakers documentation: Tangent space). Your baker's documentation will list the right preset per engine.

#The synced workflow

A synced (or synced normals) workflow means the baker and the engine use exactly the same tangent basis, on exactly the same mesh. With it, EarthQuake says, "there is simply no drawback to using hard edges along your uv seams", and you "can often get away with less uv seams" (Polycount forum: Making sense of hard edges, uvs, normal maps…). In practice:

  1. Triangulate the low poly and export it with its normals (and tangents, if your pipeline uses them).
  2. Bake with the engine's tangent space; Marmoset uses whatever "the tangent space that your mesh is currently set to" is (Marmoset: The Toolbag Baking Tutorial).
  3. Import into the engine without recomputing normals. In Unreal, Import Normals or Import Normals and Tangents (Unreal Engine documentation: FBX Import Options Reference). See smoothing, hard edges and smoothing groups.

#OpenGL (Y+) versus DirectX (Y−)

Separately from the tangent algorithm, programs disagree on which way the green channel points. Adobe: "OpenGL expects the first pixel to be at the bottom while DirectX expects it to be at the top" (Substance 3D Bakers documentation: What is the difference between the OpenGL and…). Marmoset: "Right-handedness is sometimes called OpenGL or Maya style, while left-handedness is called DirectX or 3DS Max style" (Marmoset Toolbag documentation: Tangent & Handedness).

Program Green channel Source
Unreal Engine DirectX (Y−) World of Level Design (World of Level Design); Epic's older UE3 guide: "Unreal Engine uses normal maps where the green channel is facing down" (Unreal Developer Network)
3ds Max DirectX (Y−) World of Level Design (World of Level Design); Marmoset names Y− "3DS Max style" (Marmoset Toolbag documentation)
Unity OpenGL (Y+): "Unity uses Y+ normal maps, sometimes known as OpenGL format" Unity Manual (Unity Manual)
Blender OpenGL (Y+) World of Level Design (World of Level Design)
Maya OpenGL (Y+) World of Level Design (World of Level Design); Marmoset names Y+ "Maya style" (Marmoset Toolbag documentation)
Godot OpenGL (Y+): "Godot requires the normal map to use the X+, Y+ and Z+ coordinates, this is known as OpenGL style" Godot docs (Godot documentation)

To convert between them, flip the green channel. Bakers have a toggle (Toolbag's Flip Y (Marmoset: The Toolbag Baking Tutorial)), and engines can flip on import; Unity's importer option "Indicates whether to invert the green channel values of a normal map" (Unity Scripting Reference: TextureImporter.flipGreenChannel). Adobe's advice for any other program: "refer to the target application in which your textures will be used" (Substance 3D Bakers documentation: What is the difference between the OpenGL and…).

#Common mistakes

normal map · baking · smoothing, hard edges and smoothing groups · triangulation · coordinate systems and handedness · fixing baking artefacts

#Further reading and watching

References

  1. Blender Foundation · Render Baking (Cycles) · Blender Manual (2.93), 2021 · docs · accessed 2026-10-21
  2. Morten S. Mikkelsen · mikktspace.h (MikkTSpace source header) · GitHub (mmikk/MikkTSpace), 2011 · docs · accessed 2026-10-21
  3. Marmoset · Baking Tips & Tricks · Marmoset Toolbag documentation, 2025 · docs · accessed 2026-10-21
  4. Adobe · Triangulating before baking · Substance 3D Bakers documentation · docs · accessed 2026-10-21
  5. Marmoset · Tangent & Handedness · Marmoset Toolbag documentation · docs · accessed 2026-10-21
  6. Adobe · Tangent space (Substance bakers) · Substance 3D Bakers documentation · docs · accessed 2026-10-21
  7. Unity Technologies · Model tab (FBX Importer) · Unity Manual · docs · accessed 2026-10-21
  8. Epic Games · FBX Import Options Reference · Unreal Engine documentation · docs · accessed 2026-10-21
  9. EarthQuake (Joe Wilson) · Making sense of hard edges, uvs, normal maps and vertex counts · Polycount forum, 2012 · forum · accessed 2026-10-21
  10. Joe Wilson · The Toolbag Baking Tutorial · Marmoset, 2017 · article · accessed 2026-10-21
  11. Adobe · What is the difference between the OpenGL and DirectX normal format? · Substance 3D Bakers documentation · docs · accessed 2026-10-21
  12. AlexG · DirectX vs OpenGL: Understanding, Using, Creating DirectX or OpenGL Normal Map Formats · World of Level Design, 2026 · article · accessed 2026-10-21
  13. Epic Games · Creating Normal Maps · Unreal Developer Network (UE3/UDK documentation) · docs · accessed 2026-10-21
  14. Unity Technologies · Normal map (Bump mapping) · Unity Manual · docs · accessed 2026-10-21
  15. Godot Engine contributors · Standard Material 3D and ORM Material 3D (documentation source) · Godot documentation (GitHub) · docs · accessed 2026-10-21
  16. Unity Technologies · TextureImporter.flipGreenChannel · Unity Scripting Reference (6.3 LTS) · docs · accessed 2026-10-21

Last updated 2026-10-22