Use aoMap in Three.js MeshStandardMaterial
This article explains how to utilize an aoMap (Ambient
Occlusion map) with MeshStandardMaterial in Three.js to add
realistic, pre-calculated shadows to your 3D models. You will learn how
to load the ambient occlusion texture, apply it to the material, adjust
its intensity, and configure the critical second UV channel required for
the map to display correctly.
1. Load the Ambient Occlusion Texture
To use an ambient occlusion map, you must first load the texture
using the TextureLoader.
import * as THREE from 'three';
// Create a texture loader
const textureLoader = new THREE.TextureLoader();
// Load the AO map texture
const aoTexture = textureLoader.load('path/to/your/ambient_occlusion_map.png');2. Set Up the MeshStandardMaterial
Once the texture is loaded, assign it to the aoMap
property of your MeshStandardMaterial. You can also control
the darkness of the shadows using the aoMapIntensity
property, which accepts a float value (default is 1).
const material = new THREE.MeshStandardMaterial({
color: 0xffffff,
roughness: 0.5,
metalness: 0.1,
aoMap: aoTexture, // Apply the AO map
aoMapIntensity: 1.5 // Adjust shadow intensity (default is 1)
});3. Configure the Second UV Channel (UV2)
In Three.js, ambient occlusion maps require a second set of UV
coordinates (uv2) on the geometry to map the texture
correctly. If your 3D model does not already contain a second UV channel
(often exported from software like Blender), you must generate it.
You can copy the primary UV coordinates to the secondary UV channel using the following code:
const geometry = new THREE.BoxGeometry(1, 1, 1);
// Copy the 'uv' attribute to 'uv2'
const uvAttribute = geometry.attributes.uv;
geometry.setAttribute('uv2', new THREE.BufferAttribute(uvAttribute.array, 2));If you are loading a model using GLTFLoader, you can traverse the scene and automatically apply the UV2 channel to all meshes:
gltfLoader.load('model.gltf', (gltf) => {
gltf.scene.traverse((child) => {
if (child.isMesh) {
const geometry = child.geometry;
// Ensure uv2 exists if an aoMap is used
if (geometry.attributes.uv && !geometry.attributes.uv2) {
geometry.setAttribute('uv2', new THREE.BufferAttribute(geometry.attributes.uv.array, 2));
}
}
});
scene.add(gltf.scene);
});4. Create the Mesh
With the geometry and material configured, combine them into a mesh and add it to your Three.js scene.
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);