MeshDepthMaterial vs MeshDistanceMaterial in Three.js
This article explores the differences between
MeshDepthMaterial and MeshDistanceMaterial in
Three.js, focusing on their distinct roles in shadow mapping. You will
learn how these materials calculate depth, which light types utilize
them, and how to implement them to achieve accurate shadow rendering in
your 3D scenes.
The Core Difference in Depth Calculation
The fundamental difference between these two materials lies in how they measure and record distance from the light source to the object’s surface.
- MeshDepthMaterial renders an object by depth based on the camera’s near and far planes. It measures depth along the camera’s local Z-axis (planar depth). The closer an object is to the camera, the whiter (or blacker, depending on configuration) it appears.
- MeshDistanceMaterial renders an object’s distance relative to a specific 3D point in space. Instead of using planar Z-depth, it calculates the actual Euclidean distance (radial distance) from the origin of a point light source to the fragment.
How Three.js Uses Them for Shadow Mapping
Three.js automatically selects between these two materials behind the scenes when generating shadow maps, depending on the type of light source casting the shadow.
1. Orthographic and Perspective Shadows (MeshDepthMaterial)
Directional lights and spotlights project shadows from a single
direction. To generate shadow maps for these lights, Three.js uses a
standard camera (orthographic for DirectionalLight,
perspective for SpotLight) and renders the scene’s depth
using MeshDepthMaterial.
Because these cameras look in a single direction, measuring the linear Z-depth along the camera’s view axis is sufficient to determine which objects are in front of others.
2. Omnidirectional Shadows (MeshDistanceMaterial)
Point lights cast shadows in all directions (360 degrees). To achieve this, Three.js uses a cube map consisting of six virtual cameras pointing in different directions.
Using standard planar Z-depth (MeshDepthMaterial) for a
point light would cause severe distortion at the edges of the six camera
frustums, resulting in mismatched shadow seams. To prevent this,
Three.js uses MeshDistanceMaterial for point light
shadow maps. This material records the absolute radial distance from the
center of the light source, ensuring seamless, spherically accurate
shadows across the entire cubemap.
Custom Shadow Materials
When you write custom shaders or use textures with alpha maps (transparency), the default shadow map generation might not render shadows correctly. In these cases, you must manually assign custom shadow materials to your meshes:
- Use
mesh.customDepthMaterialwhen working with directional or spot lights. - Use
mesh.customDistanceMaterialwhen working with point lights.
By assigning the correct material type to these properties, you ensure that custom vertex displacements or alpha-cutout textures are respected during the shadow map rendering pass.