EXT_materials_bump vs glTF Normal Mapping

In the glTF 2.0 ecosystem, simulating surface relief without increasing geometric complexity is essential for real-time rendering performance. While core glTF relies on standard tangent-space normal mapping via the normalTexture property, the EXT_materials_bump extension introduces support for traditional height-based bump mapping. This article examines how these two approaches fundamentally differ in data representation, runtime computation, memory consumption, mesh requirements, and visual fidelity.

Data Representation and Encoding

The primary distinction between the two approaches lies in the data stored within the texture:

  • Standard Normal Mapping: Uses a three-channel (RGB) or two-channel texture to store directional vectors. Each pixel encodes an explicit surface normal perturbed relative to the surface's tangent space, where RGB channels correspond directly to the X, Y, and Z vector coordinates.
  • EXT_materials_bump: Uses a single-channel (grayscale) height map. Pixels store scalar values representing relative elevation or surface displacement rather than directional vectors.

Runtime Shader Computation

Because the textures store different types of data, the GPU must process them differently to calculate surface lighting:

  • Standard Normal Mapping: The fragment shader performs a direct texture lookup, unpacks the sampled color from the \([0, 1]\) range to the \([-1, 1]\) vector range, and transforms it using the Tangent-Bitangent-Normal (TBN) frame. This operation is computationally lightweight and straightforward.
  • EXT_materials_bump: The fragment shader cannot use the sampled scalar value directly. Instead, it must dynamically compute the surface normal by evaluating the gradient of the height values across adjacent pixels. This is typically done using screen-space partial derivatives (such as dFdx and dFdy) or multi-tap sampling algorithms to approximate the slope of the surface at runtime.

Vertex and Mesh Requirements

Both methods affect the requirements placed on the underlying mesh geometry:

  • Standard Normal Mapping: Strictly requires a consistent tangent space across the mesh. To prevent lighting discontinuities, glTF assets typically require precomputed vertex tangents (often adhering to the MikkTSpace standard) stored directly in the mesh attributes.
  • EXT_materials_bump: Can generate perturbed normals procedurally using surface position derivatives and texture coordinate gradients. This reduces the strict necessity for precomputed vertex tangents, simplifying mesh export pipelines in specific workflows.

Memory Footprint and Performance

Each technique introduces different performance trade-offs:

  • Memory Usage: EXT_materials_bump is more memory-efficient. A bump map requires only a single 8-bit or 16-bit channel, reducing texture file size, VRAM usage, and bandwidth compared to a standard normal map that requires two or three channels.
  • GPU Processing: Standard normal mapping is more computationally efficient in the fragment stage. Bump mapping shifts the burden to the ALU by requiring real-time derivative calculations or multiple texture fetches per pixel to derive the surface slope.

Visual Quality and Artifacts

  • Precision: Standard normal maps provide smooth, consistent shading across varying viewing angles and distances because the vector direction is explicitly precalculated.
  • Derivative Artifacts: Height-derived bump maps from EXT_materials_bump can suffer from stair-stepping, aliasing, or precision loss, particularly when using standard 8-bit height maps. High-frequency details can become unstable across mipmap levels if the shader's derivative calculations are not properly filtered.