Filter Three.js Raycaster Intersections with Layers

In Three.js, the Raycaster is commonly used for mouse picking, collision detection, and user interaction. By default, a raycaster tests for intersections with all specified objects in a scene, which can be computationally expensive and structurally inefficient. This article explains how to use the Three.js Layers object to selectively filter which objects a Raycaster can interact with, allowing you to ignore specific meshes and optimize your application’s performance.

To filter intersections, you must align the layer membership of both your 3D objects and your Raycaster. By default, all Three.js objects (including cameras, lights, meshes, and raycasters) are assigned to layer 0. Three.js supports up to 32 distinct layers (indexed from 0 to 31), represented as a 32-bit mask.

Step 1: Assign Objects to Specific Layers

First, assign your target meshes to a specific layer channel using the .layers property. You can use .set() to assign an object to a single layer, which disables all other layers for that object.

const interactableMesh = new THREE.Mesh(geometry, material);
const backgroundMesh = new THREE.Mesh(geometry, material);

// Assign the interactable mesh to Layer 1 (and remove it from Layer 0)
interactableMesh.layers.set(1);

// Leave the background mesh on the default Layer 0

Step 2: Configure the Raycaster’s Layers

By default, the Raycaster is configured to only inspect objects on layer 0. To make it inspect objects on layer 1 instead, you must update the raycaster’s .layers object to match.

const raycaster = new THREE.Raycaster();

// Tell the raycaster to only intersect with objects on Layer 1
raycaster.layers.set(1);

Step 3: Perform the Intersection Check

When you call intersectObjects(), the raycaster will automatically bypass any objects that do not share an active layer with it.

// This will only return intersections with objects on Layer 1
const intersects = raycaster.intersectObjects(scene.children, true);

In this setup, even if backgroundMesh (on layer 0) is physically positioned directly in front of interactableMesh (on layer 1), the raycaster will pass straight through the background mesh and only detect the interactable mesh.

Managing Multiple Layers

If you want an object or a raycaster to exist on multiple layers simultaneously, use the .enable() method instead of .set().

// Enable Layer 1 and Layer 2 on the raycaster
raycaster.layers.enable(1);
raycaster.layers.enable(2);

// Disable a specific layer if needed
raycaster.layers.disable(0);

Using the Layers object is the most efficient way to manage raycasting groups in Three.js, as the filtering happens internally during the raycasting traverse loop, saving valuable CPU cycles.