Why glTF Requires Linear Normal and Roughness Maps

In modern Physically Based Rendering (PBR) pipelines, maintaining accurate material definitions depends entirely on how texture data is decoded. The glTF 2.0 specification strictly mandates that metallic-roughness and normal maps be sampled in linear color space rather than an sRGB transfer function. Because these textures store raw mathematical parameters and spatial vectors rather than optical visual color, applying gamma correction curves alters the encoded values, leading to distorted surface reflections, incorrect light scattering, and broken lighting calculations.

The Purpose of Color Spaces: Data vs. Perception

The sRGB color space was developed to accommodate non-linear human visual perception, allocating more bandwidth to darker tones where the human eye is more sensitive. While base color (albedo) maps represent visual light and must be converted from sRGB to linear space for accurate rendering, data textures do not represent perceived light. They represent raw scalar quantities and geometric coordinates. Sampling data maps with an sRGB-to-linear curve inadvertently applies a power function (approximately \(x^{2.2}\)) to values that are already linearly defined, corrupting the underlying math.

Why Metallic-Roughness Maps Must Remain Linear

In glTF, the metallic-roughness texture packs two distinct physical parameters into a single image file:

  • Green Channel: Roughness (perceptually linear roughness factor)
  • Blue Channel: Metalness (scalar mask indicating dielectric vs. conductor)

These parameters are linear multipliers used directly in microfacet bidirectional reflectance distribution function (BRDF) formulas, such as GGX/Trowbridge-Reitz.

If a rendering engine interprets this texture as sRGB, it attempts to "linearize" the values by applying the standard sRGB inverse curve. This causes mid-tone values to shift dramatically toward zero (darker). A roughness value of 0.5 would be mathematically warped to approximately 0.21, making surfaces appear substantially glossier than intended. Similarly, transitional metalness values get compressed, causing edge artifacts and incorrect Fresnel reflectance calculations.

Why Normal Maps Require Linear Interpretation

Normal maps encode unit vectors representing surface orientations rather than colors. In a standard tangent-space normal map:

  • Red Channel: X-axis deviation \([-1, 1]\)
  • Green Channel: Y-axis deviation \([-1, 1]\)
  • Blue Channel: Z-axis deviation \([0, 1]\)

To store these negative and positive directional values in standard 8-bit image formats, the vectors are linearly mapped to a normalized \([0, 1]\) range using the formula:

\[\text{Encoded Value} = 0.5 \times \text{Vector} + 0.5\]

When the GPU shader reconstructs the normal vector, it reverses this calculation:

\[\text{Decoded Vector} = 2.0 \times \text{Sampled Value} - 1.0\]

This reconstruction relies on a strictly linear relationship. If the normal texture is decoded as sRGB, the transformation curve bends the vector components unevenly. Neutral flat surfaces (encoded as RGB: 128, 128, 255) shift away from the direct surface normal, creating unintended slopes, broken light reflections, incorrect tangent space calculations, and severe shading artifacts.

The glTF Standard and Cross-Engine Consistency

The glTF 2.0 specification enforces linear handling of all non-color data maps (including ambient occlusion) to guarantee visual parity across all rendering environments. Whether rendered in WebGL engines like Three.js and Babylon.js, or imported into digital content creation tools and game engines like Blender and Unreal Engine, marking these textures as linear ensures that the mathematical inputs match the author's original physical intent.