How to Use Metalness Maps in Three.js PBR Materials
In modern 3D web development, achieving realistic surfaces requires
Physically Based Rendering (PBR). This article explains how to use a
metalness map within a Three.js MeshStandardMaterial to
define which areas of a 3D model’s texture are conductive (metallic) and
which are dielectric (insulators). You will learn how a metalness map
works, how to load it using the TextureLoader, and how to
properly configure your material properties to achieve accurate visual
results.
Understanding the Metalness Map
A metalness map is a grayscale texture where pixel values determine the metallic properties of a surface: * White (1.0) represents fully conductive, metallic surfaces (such as steel, gold, or copper). * Black (0.0) represents non-conductive, dielectric surfaces (such as wood, plastic, or stone). * Gray values represent transitional states, often used for dirt, dust, or rust covering a metal surface.
In Three.js, these values are multiplied by the material’s overall
metalness property.
Step-by-Step Implementation
To apply a metalness map in Three.js, you must load the texture,
configure its color space, and assign it to a compatible PBR material
like MeshStandardMaterial or
MeshPhysicalMaterial.
1. Load the Texture
Use the THREE.TextureLoader to load your grayscale
metalness map. Because a metalness map contains mathematical data rather
than color information, you must set its color space to
THREE.NoColorSpace (or linear filtering) to prevent
Three.js from applying gamma correction.
import * as THREE from 'three';
// Initialize the texture loader
const textureLoader = new THREE.TextureLoader();
// Load the metalness map texture
const metalnessMap = textureLoader.load('textures/metalness.jpg');
// Set the correct color space for data textures
metalnessMap.colorSpace = THREE.NoColorSpace;2. Configure the PBR Material
Create a MeshStandardMaterial and pass the loaded
texture to the metalnessMap property. To ensure the map
displays correctly, you must set the scalar metalness
property to 1.0.
const material = new THREE.MeshStandardMaterial({
color: 0xaaaaaa, // Base color of the material
metalnessMap: metalnessMap, // The loaded grayscale map
metalness: 1.0, // Multiplier (must be 1.0 to use the map's full range)
roughness: 0.2 // Standard roughness value
});If the metalness property is set to 0.5,
the maximum metalness on the white parts of the map will only reach 50%
conductivity. Keeping it at 1.0 ensures the map dictates
the exact metallic values of the surface.
3. Pair with Roughness for Realism
Metalness maps work best when paired with a
roughnessMap. Metals reflect light differently based on how
polished they are. Providing both maps allows you to define shiny metal
parts alongside dull, rough non-metal parts on the same 3D mesh.
const roughnessMap = textureLoader.load('textures/roughness.jpg');
roughnessMap.colorSpace = THREE.NoColorSpace;
const pbrMaterial = new THREE.MeshStandardMaterial({
map: colorTexture, // Base color texture
metalnessMap: metalnessMap,
metalness: 1.0,
roughnessMap: roughnessMap,
roughness: 1.0 // Multiplier for the roughness map
});By combining these properties, Three.js processes the metalness map to determine the reflectivity and color preservation of light bounces, producing realistic, physically-accurate renders on the web.