WebXR Lighting Estimation with Three.js
Integrating real-world lighting into a virtual scene creates highly realistic Augmented Reality (AR) experiences. This article explains how to configure a WebXR session using the WebXR Light Estimation API and apply those real-time lighting values to illuminate a Three.js scene, ensuring your 3D models seamlessly match the brightness, color, and reflections of the physical environment.
1. Request the Light Estimation Feature
To use lighting estimation, you must request the
light-estimation feature when initializing your WebXR
session. In Three.js, this is configured using the ARButton
utility by passing the feature into the optionalFeatures or
requiredFeatures array.
import { ARButton } from 'three/addons/webxr/ARButton.js';
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.xr.enabled = true;
document.body.appendChild(ARButton.createButton(renderer, {
optionalFeatures: ['light-estimation']
}));2. Use the Three.js XREstimatedLight Helper
Three.js provides a built-in helper class called
XREstimatedLight that handles the complex math of
converting WebXR light probe data (spherical harmonics and environment
maps) into light sources that Three.js materials can use.
Import the helper and instantiate it by passing your renderer:
import { XREstimatedLight } from 'three/addons/webxr/XREstimatedLight.js';
const xrLight = new XREstimatedLight(renderer);3. Handle Estimation Events
The XREstimatedLight object dispatches events when the
WebXR session starts estimating light. You must listen for these events
to add the light sources to your scene and apply the generated
environment map for realistic reflections.
xrLight.addEventListener('estimationstart', () => {
// Add the estimated directional and ambient lights to the scene
scene.add(xrLight);
// Apply the estimated environment map to the scene for reflections
if (xrLight.environment) {
scene.environment = xrLight.environment;
}
});
xrLight.addEventListener('estimationend', () => {
// Remove the lights and reflections if estimation stops
scene.remove(xrLight);
scene.environment = null;
});4. Render the Scene
Once configured, Three.js automatically updates the light’s
intensity, color, direction, and environment map on every frame of the
XR animation loop. Ensure your materials (such as
MeshStandardMaterial or MeshPhysicalMaterial)
are configured to receive shadows and reflections to take full advantage
of the real-world illumination.