Configure DirectionalLight Shadow Camera in Three.js
Configuring the shadow camera bounds for a
DirectionalLight in Three.js is essential for achieving
sharp, high-quality shadows without sacrificing performance. Because
directional lights project shadows using an orthographic projection, you
must manually define a bounding box (frustum) that encapsulates only the
objects in your scene that cast or receive shadows. This guide provides
a direct, step-by-step approach to setting up, optimizing, and
visualizing these shadow camera boundaries.
Understanding the Shadow Camera
In Three.js, a DirectionalLight uses an
OrthographicCamera hidden inside its shadow
property to render shadow maps. This camera is configured using six main
boundaries: left, right, top,
bottom, near, and far.
If this bounding box is too large, your shadows will look pixelated and blurry because the shadow map texture is stretched over too wide an area. If the box is too small, shadows will be clipped or cut off.
Step-by-Step Configuration
To properly configure the shadow camera, you need to adjust its boundary properties and update its projection matrix.
1. Enable Shadows and Set Resolution
First, enable shadow casting on your directional light and set the resolution of your shadow map. Higher values yield sharper shadows but cost more performance.
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(10, 20, 10);
light.castShadow = true;
// Set the shadow map resolution (must be powers of 2)
light.shadow.mapSize.width = 2048;
light.shadow.mapSize.height = 2048;2. Define the Camera Bounds
Adjust the left, right, top,
bottom, near, and far properties
of the shadow camera. Keep these boundaries as tight as possible around
your active scene objects.
const d = 15; // The reach of the shadow camera from the light's center
light.shadow.camera.left = -d;
light.shadow.camera.right = d;
light.shadow.camera.top = d;
light.shadow.camera.bottom = -d;
// Define how close and how far the camera looks
light.shadow.camera.near = 0.5;
light.shadow.camera.far = 50;3. Update the Projection Matrix
Whenever you modify the shadow camera’s properties, you must tell Three.js to recalculate its projection mathematical matrix.
light.shadow.camera.updateProjectionMatrix();
scene.add(light);4. Visualize the Bounds (Crucial for Debugging)
It is highly recommended to use the CameraHelper to
visually inspect the boundary box in your scene. This lets you see
exactly where the shadow camera is cutting off.
const shadowHelper = new THREE.CameraHelper(light.shadow.camera);
scene.add(shadowHelper);Using this helper, adjust the d variable (and the
near/far planes) until the yellow helper box
snugly fits your 3D models. Once you are satisfied with the shadow
quality and coverage, you can remove or hide the helper.