Raycasting & object interaction

Back to Modules

Raycasting and Object Interaction in Three.js

Raycasting is a fundamental technique in 3D graphics used to determine if a ray (an imaginary line extending infinitely in one direction) intersects with any objects in a 3D scene. In Three.js, this is commonly used for enabling user interaction, such as detecting mouse clicks or hovers on 3D objects.

How Raycasting Works

The process generally involves:

  1. Defining a Ray: A ray is defined by an origin (starting point) and a direction. For mouse interaction, this ray typically originates from the camera's position and extends through the 3D point corresponding to the 2D mouse cursor on the screen.
  2. Checking for Intersections: The raycaster then checks for intersections between this ray and the objects in your scene.
  3. Processing Intersections: If intersections are found, the raycaster returns a list of intersected objects, ordered by distance from the ray's origin.

Key Components for Raycasting

Implementing Object Interaction with Raycasting

1. Initialize Raycaster and Mouse Vector

const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();

2. Update Mouse Coordinates

Attach an event listener (e.g., mousemove or click) to your renderer's DOM element to update the mouse vector whenever the mouse moves or is clicked. You need to convert the screen coordinates to NDC.

function onMouseMove(event) {
    // Calculate mouse position in normalized device coordinates (-1 to +1)
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}

window.addEventListener('mousemove', onMouseMove, false);

3. Perform Raycasting in your Animation Loop or on Event

In your animation loop (or within your event handler), you'll update the raycaster and check for intersections.

// Update the picking ray with the camera and mouse position
raycaster.setFromCamera(mouse, camera);

// Calculate objects intersecting the picking ray
const intersects = raycaster.intersectObjects(scene.children, true); // 'true' for recursive check

if (intersects.length > 0) {
    const intersectedObject = intersects[0].object;
    console.log('Intersected object:', intersectedObject.name || intersectedObject.uuid);
    // Perform actions, e.g., change color, display info, select object
} else {
    // No intersection
}

Example: Hover and Click Interaction

This example demonstrates how to change the color of a cube when you hover over it and log a message when you click it.