Houdini 20.0 Materials

Adding detail with normal, bump, and displacement mapping

On this page


Normal, bump, and displacement maps are ways to create the appearance of high-resolution geometry on low-resolution models by adding detail at display/render time.

In this image, the head on the left is a low-res model, the head in the middle is a highly detailed high-res model. The head on the right is the low-res model with a normal map generated from the hi-res model. It is visually almost indistinguishable from the high-poly model.

Image credit: Akin Bilgic.

The different types of detail maps have different tradeoffs.

Normal Maps & Bump Maps

Normal and bump maps create the appearance of additional surface detail by changing normals at render time, without actually creating additional geometry. This makes them faster and use less memory.

  • Bump maps store height deltas as grey levels in a monochrome map.

  • Normal maps store vectors as RGB in a color map.

Because they only change the normal, they do not affect the silhouette of the object. For example, if you add normal mapping to a sphere, you can make the surface area of the sphere look rough and craggy, but the edges will still be perfectly smooth.

Displacement Mapping

Displacement maps add actual new geometry at render time. The renderer subdivides the existing geometry and the moves it according to the texture values.

  • Displace Along Normal stores height deltas, similar to bump maps.

  • Vector Displacement stores offset vectors as RGB. The vectors can be in tanget, object, or world space.

    In contrast to Displace Along Normal, this allows parts of a surface to arch over neighboring parts.





Memory usage

Memory used by the texture, ideally greyscale.

Memory used by the texture, must be RGB.

Uses more memory for 16/32 bits to avoid banding. Potentially large memory usage for lots of small polygons †.

Rendering speed

Small slowdown, requires multiple texture samples.

Faster, single texture sample.

Slower in raytracing/PBR because it adds polygons †.

Startup time

Small impact due to texture loading.

Small impact due to texture loading.

Larger impact with raytracing/PBR because renderer must generate displaced geometry.

Art workflow

Easy to manipulate in 2D apps, but can be hard to get desired result painting in 2D. Can be baked by rendering a height pass in 3D applications.

Requires specialized texture painting tools. Can be baked from a high-resolution model or generated from a normal pass.

Similar to bump maps.

† Displacement mapping has less of an impact on render time and memory usage if you are using micropolygon rendering with no raytracing (for example, no raytraced shadows).

How to

To...Do this

Generate a detail map

Use the Bake Texture ROP to export the maps as an extra image plane in a render.

Use a detail map

The /nodes/shop/principledshader.html and the Mantra Surface Shader have parameters to specify different types of detail maps to apply to the shaded surfaces.

Use a detail map in a custom shader

Use the Displace and/or Displacement Texture VOPs.

Masterclass video

This masterclass video covers detail maps.

Normal map formats

You can store normals in a texture in a few ways. Unfortunately, there is no clearly defined standard, so mantra shaders have a few options to account for these different formats.

Vector space

Tangent space

Stores the normal relative to the tangent space of the surface. Normals will still look right when the surface deforms, like the skin of an animated character.

World space

Stores normals relative to world space. If the surface moves or deforms, it will appear to swim through a texture anchored in place. You should generally only this for static geometry. World space maps preserve sharp cusps better than tangent-space maps.

Object space

Stores normals relative to the object transform. Objects can move, but if they deform the normals will not look right.

[0,1] vs [-1,1]

The values of a normal vector are naturally in the [-1,1] range.

Since negative texture values are difficult to work with and impossible to store in some texture formats, applications usually remap the values to the [0,1] range before they're stored in a texture.

When rendering with textures stored in this format, leave the Normal Space parameter on mantra shaders at the default of 0 to 1.

Formats like .rat and .exr can store the normals using their natural [-1,1] range, so you may sometimes encounter textures that are stored this way. In this case set Normal Space to -1 to 1.

Flipped X & Y

Textures exported from some packages will have the Y, and more rarely the X component flipped. If your texture imports flipped, use the Flip X and Flip Y parameters on mantra shaders to correct it.

Color Space

You should store detail maps in linear color space. If you save a map in an image format that is natively sRGB (such as TIFF, JPEG, or PNG), you must avoid applying gamma to the image.

  • If you write a detail map with the Composite ROP, turn off Convert to Image Format’s Colorspace.

  • If you load a map in a Texture VOP, set the color space to Linear to prevent gamma correction.

  • If you load a map into the compositor with a File COP, turn off Linearize Non-Linear Images.

Create a tangent-space normal map from a height map

You can create a normal map from a height (or displacement) map in Houdini’s compositor.

  1. Load the height map in a File COP. Turn off Linearize Non-Linear Images (to prevent gamma correction).

  2. Append a Gradient COP.

    Set the Gradient Type to “Displacement”, and the Output to “Normal Map”.

    Use the Scale parameter to adjust the normals. The inverse of the displacement map scale used by the material is a good scale to use: 1/(maximum displacement).

  3. Append a ROP File Output node. Set the Output Filename and turn off Convert to Image Format’s Colorspace to avoid gamma correction.

See also


Using materials

Textures and UVs

Creating materials

Guru level

Other renderers