What is raycasting in three.js?

Three.js is a JavaScript library that is built on top of WebGL and is used for rendering animations on the web.

Raycasting is a way to determine where the user's mouse is pointing in a 3D scene. This technique is generally used in graphics programming as well.

In Three.js, raycasting can be achieved using Vector2D and the Raycaster. The Raycaster is given the coordinates of the mouse on the screen, and it creates a ray normal to the mouse's position. This allows the Raycaster to determine the objects that the ray is intersecting using the intersectObjects method. This is explained in more detail below.

Syntax

The syntax for using the Raycaster is as follows:

const raycaster = new THREE.Raycaster();

Here, along with the Raycaster, we also need to initialize a Vector2. A Vector2 is a two-dimensional vector that only contains the xx and yy coordinates. We use this to track the movement of the cursor on the screen.

After the initialization, we need to add an event listener for cursor movement by using addEventListener and define the function which will be called whenever the event listener captures mouse movement.

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

Here, we give addEventListener the mousemove event to listen for and define the onMouseMove() function to be called whenever the mouse is moved. This is explained at a later point in the Answer.

Note: We need to add this event listener inside the rendering function along with window.requestAnimationFrame. To read more on addEventListener, please follow this link.

Updating the position of the ray

We can set the position of the ray by using either set or setFromCamera methods. An example given below uses setFromCamera as we do not have to specify the origin points of the ray and the direction in which it is cast.

raycaster.setFromCamera(pointer, camera);

Here, setFromCamera takes in two parameters,

  • pointer: This is the JSON object that contains the coordinates of the cursor. We need to ensure that these coordinates are normalized between -1 and 1.

  • camera: This is the THREE.Camera inside our scene.

As opposed to the method shown above, set uses the following syntax:

raycaster.set(origin, vector)
  • origin: This would have denoted the place where the ray should originate from. origin should be of type THREE.Vector3.

  • direction: This would have been the THREE.Vector3 that gave the direction of the ray.

Getting intersecting objects

Now that we can cast our ray, we can get access to the objects inside the scene being intersected by it. This can be done using intersectObject or intersectObjects. Both of these methods take, as a parameter, the object(s) to check for an intersection with. The intersectObject method takes only one object, whereas intersectObjects takes an array of objects.

const intersects = raycaster.intersectObjects(scene.children);

Here,

  • Since the scene is at the root of the scene graph, its children are all the objects inside the scene. This is what scene.children gives us access to.

  • intersects is an array that will contain the objects that the ray intersects.

Now that we have access to the objects that the ray intersects, we can perform the operations on them as we like.

Our final onMouseMove function will look like the sample given below.

const pointer = new THREE.Vector2();
function onPointerMove(event) {
pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
pointer.y = - (event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(pointer, camera);
const intersects = raycaster.intersectObjects(scene.children);
for (let i = 0; i < intersects.length; i++) {
console.log(intersects[i]);
}
}

Here,

  • Line 1: This line initializes the two-dimensional vector that we’ll use to store our mouse coordinates.
  • Line 3: This is the onMouseMove function which will be called whenever our event listener captures the cursor moving on the application screen.
  • Lines 5–6: Here, event.clientX and event.clientY are being used to get the plain xx and yy coordinates of the mouse. They are then normalized between -1 and 1.
  • Line 8: Here, we are setting the position of the Raycaster relative to the camera’s position and passing it the coordinates of the mouse, which are contained in pointer.
  • Line 10: The intersects keyword contains the array of objects being intersected by the ray.
  • Line 12–14: This for loop goes over the length of the intersects array, and we print the objects being intersected using console.log.

Example

The example below demonstrates the working of the Raycaster. The objects that the ray intersects are highlighted in red. The user can also click and drag to rotate the scene.

Note: Here, we can see that all the objects that are intersected by the ray are highlighted in red, even the ones that lie behind the ones being hovered over by the mouse.

Spheres to test raycasting on

Explanation

The HTML tab contains the boilerplate code for setting up the Three.js to run on an HTML file. Read more on how to create a scene in Three.js.

Here,

  • Line 107: Inside the function onMouseMove, we're accessing the intersecting objects' material property and changing its color to red.

Free Resources

Copyright ©2024 Educative, Inc. All rights reserved