Lighting is a key part of creating realistic 3D scenes, and the Three.js DirectionalLight
component makes it easy to add sunlight-like effects with shadows. In this blog, we’ll explore how to work with DirectionalLight
in Three.js, focusing specifically on how to use shadows with this light source to enhance the depth and realism of a scene. We’ll use a code example to explain each step in setting up and customizing shadows.
Setting Up Directional Light for Shadows
The DirectionalLight
in Three.js is commonly used to simulate sunlight in a 3D environment. Unlike point or spotlights, DirectionalLight
projects light in a specific direction rather than emanating from a single point. This means shadows cast by DirectionalLight
are parallel, like natural sunlight.
Here’s the code snippet we’ll use to set up a directional light with shadows:
let directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.name = 'directional';
directionalLight.castShadow = true;
directionalLight.shadow.width = 4096;
directionalLight.shadow.height = 4096;
directionalLight.position.set(200, 150, 100);
let dirLightSize = 500;
directionalLight.shadow.camera.left = -1 * dirLightSize;
directionalLight.shadow.camera.bottom = -1 * dirLightSize;
directionalLight.shadow.camera.right = dirLightSize;
directionalLight.shadow.camera.top = dirLightSize;
scene.add(directionalLight);
Let’s break down what each part of this code does.
Creating the Directional Light
The DirectionalLight
component takes two arguments: the light color (0xffffff
for white) and the light intensity (1
). Setting a name is optional but helpful when debugging or managing multiple light sources.
Enabling Shadows
let directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.name = 'directional';
directionalLight.castShadow = true;
directionalLight.shadow.width = 4096;
directionalLight.shadow.height = 4096;
Setting castShadow
to true
enables shadows for the light source, making it possible for objects in the scene to cast shadows. The shadow.width
and shadow.height
parameters define the resolution of the shadow map, which is essentially a texture that Three.js generates to represent shadows. Higher values (like 4096x4096
) produce sharper shadows but require more memory and can impact performance. Adjust these values based on the complexity and performance requirements of your scene.
Positioning the Light.
directionalLight.position.set(200, 150, 100);
The position.set()
method defines the light’s origin. This positioning controls where the light appears to come from, which will affect where shadows fall. For a sun-like effect, you’ll typically place the light at a high position and offset it from the scene’s center.
Configuring the Shadow Camera
let dirLightSize = 500;
directionalLight.shadow.camera.left = -1 * dirLightSize;
directionalLight.shadow.camera.bottom = -1 * dirLightSize;
directionalLight.shadow.camera.right = dirLightSize;
directionalLight.shadow.camera.top = dirLightSize;
The shadow camera settings control the boundaries of the area where shadows are cast. Since directional light is infinite, defining a “shadow camera” helps Three.js limit where shadows are generated. The dirLightSize
variable determines the dimensions of this area, giving you control over how much of the scene will cast shadows. A larger dirLightSize
captures more of the scene but may make shadows less precise. Adjusting these boundaries based on the size and position of the objects in your scene can help you achieve well-defined shadows without performance issues.
Adding the Light to the Scene
scene.add(directionalLight);
Finally, adding the directional light to the scene makes it active, and Three.js will now render shadows based on this light.
Tips for Working with Directional Light Shadows
- Adjust Light Position: Moving the directional light can drastically change shadow length and orientation.
- Fine-tune Shadow Quality: Higher resolutions improve shadow sharpness but may reduce performance. Experiment with values like
1024
or2048
if4096
is too demanding. - Optimize Shadow Boundaries: The shadow camera’s left, right, top, and bottom boundaries should be just large enough to cover the objects that need shadows. This minimizes rendering load and improves shadow quality.
Illustrations with real projects
The size of the camera left, right, top and bottom at 20
The size of the camera left, right, top and bottom increased to 150
Conclusion
Adding shadows with Three.js’s DirectionalLight
can add a sense of realism to your 3D scenes. With the code and explanations provided, you’re now equipped to set up and customize shadows for various scenarios, enhancing the depth and overall visual appeal of your projects. Experiment with different values and settings to find the best balance between quality and performance for your specific use case!