Skip to content

Normal to Height

Normal to Height
Texture

Normal to Height turns a tangent-space normal map back into a height map. Most downloaded and painted materials ship a normal map and no height, and this node lets them feed anything that wants a surface rather than a direction. Wire a normal map into the Normal input and take the Height output into Ambient Occlusion, Curvature, Height Layer, Texture Layer, Displace, or the Height input of a Texture node.

A normal map stores slope: which way the surface tilts at each point. It stores neither absolute height nor scale, so for any tool that does this job:

  • A hard step cannot be recovered. Two flat areas at different heights have identical normals, so a step comes back as a soft ramp, not a cliff. The same goes for a crack that goes straight down, or a piece floating above another.
  • The answer is right up to a constant, per covered area. Slopes never say where the surface sits. The node levels each connected covered area on its own average, and Range then places it, so two separate islands on a cutout sheet are placed independently.
  • The depth is yours to place. By default the height comes out from 0 to 1 and the node states the depth in words, so you can type it into whatever reads the map.

Within those limits the reconstruction is exact for what normal maps mostly describe: pores, grain, weave, brushed metal, bark, leather, stitching, bevels, and scratches all come back as the surface they came from.

Set Range first; it decides how the depth is carried. Normalized scales the height to 0 to 1 and reports the depth in words; the other three keep the true depth in the pixels.

  • Normalized (default) puts the map’s lowest point at 0 and its highest at 1, on one scale for the whole image, the form most height maps arrive in. Once the node has cooked, the Parameters panel states the depth directly under Range, for example “Full range is 3.8% of the shorter side. To match this normal map, set Height Depth to 3.8% on the node that reads this height, such as Ambient Occlusion or Curvature.” Copy that number into the Height Depth of Ambient Occlusion or Curvature and the surface is exactly the one the normal map describes.
  • Midgray keeps the true depth, with midgray as each covered area’s average level. Use it when several maps must agree, such as animation frames or the tiles of one material: Normalized measures each image on its own span, so two tiles can come out at different depths, while Midgray at a fixed Relief cannot.
  • From Zero keeps the true depth and puts each covered area’s lowest point at zero, for a reader that expects a height starting at the floor.
  • Signed is the height as measured: flat is zero, raised positive, recessed negative. It needs 32-bit (Float) Mode, since 8-bit cannot hold a negative value; in an 8-bit document it publishes Midgray instead.

Relief scales the output and nothing else: 1 is the relief the normal map describes (a map made with the Normal Map node comes back at the depth that went in), 2 is exactly twice that, and 0 is flat. It is hidden under Normalized, where the depth comes from the image’s own span.

Beyond what Normalized states, nothing is measured from the picture, so one hot pixel never rescales a Midgray, From Zero, or Signed map, and two tiles of one material agree.

Under Normalized, type the number from the Parameters panel, under the Range row, into the Height Depth of whatever reads the height. Skipping it is not wrong, just a different depth: every feature survives, at whatever relief the reading node’s Height Depth implies.

Under Midgray, From Zero, and Signed, the height is published in the units Ambient Occlusion and Curvature expect at their default Height Depth of 1%, so leave the downstream node alone.

Reading a map in the wrong Normal Format flips the height along one axis, so a bump comes back as a ridge running the other way. If the result looks inverted along the vertical, this is the control.

Edge Mode says what lies outside the map: Repeat (default) for a tiling material, Open for a single non-tiling image. A tiling material read as Open shows a fold at its seam; a non-tiling panel read as Repeat shows a tilt wrapped back against itself.

Real normal maps carry pixels that describe no surface: black padding around a decal, an unpainted background, compression noise along a hard edge. They point away from the surface, and no height could produce them.

The node bridges them: each takes the smooth value its neighbors imply, so nothing dents or spikes around it. The node body says what share of the map that was, for example “3% of the normal map points away from the surface and was bridged”. That note is about the input, so it stays on the node; the depth under Normalized is in the Parameters panel.

If more than half the map cannot be read, the node says so instead of guessing: “Most of this normal map points away from the surface, so no height map could produce it.” The usual causes are the wrong Normal Format, a map that is not tangent space, or a two-channel map whose blue channel is empty. A two-channel map is refused by name rather than reconstructed from the other two channels.

On a texture set or a library, a Map row reads the set’s Normal and writes the Height into the same set (adding one when the set has none), so every other map stays in place. The set’s own normal convention is used, so the Normal Format row is not shown. A set without a Normal passes through unchanged, with a note. See Changing one map.

Pins

NormalPixels or Texture
InputRequired
HeightPixels or Texture
Output

Height

MapChoice
Default: Normal
Texture set or library wired

Which map of the texture set this node reads. Its result is written into the set, and every other map passes through unchanged. Shown while a texture set or a library is wired

  • Base ColorWork on the set's Base Color. The first map for the color and tone nodes.
  • NormalWork on the set's Normal. Offered on Normal Map (rescale its intensity) and the nodes that read a map into a selection; a color node never edits a direction.
  • RoughnessWork on the set's Roughness, a linear 0 to 1 map with one channel.
  • MetallicWork on the set's Metallic, a linear 0 to 1 map with one channel.
  • Ambient OcclusionWork on the set's Ambient Occlusion, a linear 0 to 1 map with one channel.
  • HeightWork on the set's Height, a linear map that can pass 0 and 1.
  • OpacityNever offered: the Opacity is the set's cutout, which Mask Apply edits.
  • EmissiveWork on the set's Emissive color.
RangeChoice
Default: Normalized Range: Normalized / Midgray / From Zero / Signed

Where the reconstructed height sits.

  • Normalized: lowest point 0, highest 1. A note under this row gives the Height Depth that restores the true relief.
  • Midgray: average level at midgray, true relief. Use it when several maps must agree.
  • From Zero: lowest point at 0, true relief.
  • Signed: flat at 0, recesses negative. Needs 32-bit (Float) Mode.
ReliefNumber
Default: 1.000 Range: 0.000–8.000
Range ≠ Normalized

Scales the depth of the reconstructed height. 1 = true relief, the depth the normal map describes, and 2 is twice that. 0 = flat

Source

Normal FormatChoice
Default: OpenGL Range: OpenGL / DirectX
No texture set wired

Green-channel convention of the normal map. Set it to match the file.

  • OpenGL: +Y is up. The usual choice for Blender, Unity, Godot and glTF.
  • DirectX: +Y is down. The usual choice for Unreal and 3ds Max.
Edge ModeChoice
Default: Repeat Range: Repeat / Open

What lies outside the map.

  • Repeat: the map tiles, so the height carries across the seam. Use it for a tiling material.
  • Open: nothing outside, so the surface simply ends and an overall tilt in the map is kept.
  • Load a normal map file with Input Color Space set to Normal Map on Image In or Image Folder, so its values reach this node unchanged. A texture set’s own Normal is already read correctly; wire the set straight in (see Texture sets).
  • A round trip is a quick check: a height map through Normal Map and back through this node on Midgray gives the surface you started with, at the matching depth.
  • Over a cutout (an image’s alpha, or a texture set’s Opacity), only the opaque part is solved, and each connected island is placed on its own. Transparent pixels publish midgray under Midgray and black under the other three.
  • Work in 32-bit (Float) Mode, the default for new projects, to keep full precision from the normal map to the height and into whatever reads it.
  • Search the node library for “normal to height”, “height from normal”, “integrate”, “relief”, or “bump”.