Bump Map vs Displacement Map in Three.js

This article explains the specific visual and structural differences between bump maps and displacement maps in Three.js. While both textures are used to add depth and detail to 3D surfaces, they do so using entirely different rendering techniques. Understanding these differences will help you choose the right approach for your WebGL projects to balance visual fidelity and performance.

The Core Visual Differences

The fundamental visual difference between a bump map and a displacement map lies in how they affect the silhouette of a 3D object and how they interact with light.

1. Silhouette and Edge Profile

2. Shadows and Self-Shadowing

3. Viewing Angles (The Grazing Angle Limit)


Technical Implementation in Three.js

The visual differences stem from how Three.js processes these maps in the shaders.

Bump Map (MeshStandardMaterial.bumpMap)

Three.js uses the grayscale values of the bump map to perturb the surface normals during the fragment shader step. * Geometry Requirement: Works on low-polygon meshes. You do not need a highly detailed mesh to achieve the effect. * Three.js Properties: Controlled via bumpMap and bumpScale (which dictates the perceived depth of the bumps).

const material = new THREE.MeshStandardMaterial({
  color: 0x888888,
  bumpMap: bumpTexture,
  bumpScale: 0.05
});

Displacement Map (MeshStandardMaterial.displacementMap)

Three.js uses the grayscale values of the displacement map to physically reposition the vertices of the mesh during the vertex shader step. * Geometry Requirement: Requires a highly subdivided mesh. If your mesh only has a few vertices, there is nothing for the displacement map to move, resulting in a distorted or blocky appearance. * Three.js Properties: Controlled via displacementMap, displacementScale (how far the vertices are pushed), and displacementBias (the offset of the displacement).

// High polygon count is required for displacement
const geometry = new THREE.PlaneGeometry(10, 10, 128, 128); 

const material = new THREE.MeshStandardMaterial({
  color: 0x888888,
  displacementMap: displacementTexture,
  displacementScale: 0.5,
  displacementBias: 0
});

Summary of When to Use Which