To calculate which object the mouse clicked on in three dimensions, you essentially send out a ray from that point and see which objects the line passes through.

Before that, let’s get familiar with the coordinate system of three-dimensional space. In threeJs, we use the right-handed coordinate system, with the center point of the screen as the origin. The coordinates range from -1 to 1.


Normal pages are two-dimensional coordinates, starting with the upper left corner. And the coordinate range is taken from the actual pixel position of the screen size (x, y).


Now that you’re familiar with coordinates, here’s how to calculate which object the mouse clicked in three dimensions, roughly in four steps.

1. Obtain the coordinate position (x1, y1) when clicking, which is the coordinate position in the two-dimensional picture.

2. Convert the above (x1, y1) to the 3d coordinate position (x2, y2). Here (X2, y2) is still the 2d coordinate position, but it is calculated from the center of the screen.

3. Normalize (x2, y2) to get (x3, y3), because the value of three-dimensional coordinates ranges from -1 to 1.

4. Use the Raycaster ray in ThreeJs to get the object that the ray from the current point passes through.


Let’s start the calculation process:

Step 1: Get the mouse click position event.clientX, event.clientY (x1, y1).

Step 2: x2 = x1 – (innerWidth / 2), y2 = (innerHeight / 2) -y1 The Y-axis of the two-dimensional coordinate is opposite to the Y-axis of the three-dimensional coordinate.

Step 3: x3 calculation as shown in the figure:


Step 4:

 // Raycaster ray pickup
 const rayRaster = new THREE.Raycaster();
 const mouse = new THREE.Vector2();

 function onClick(event) {
 
     // Calculate the coordinates and use the formula directly
     mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
     mouse.y = 1 - (event.clientY / window.innerHeight) * 2;
     
     / / ray
     rayRaster.setFromCamera(mouse, camera);
     
     // The object that the ray passes through, that is, the object in the point
     // Returns an array of all clicked objects
     const intersects = rayRaster.intersectObjects(Scene.children);
     
     // If the length of the ray passes through some object, take the first one.
     if (intersects.length) {
         console.log(intersects[0]); }}document.body.addEventListener('click', onClick, false);

Copy the code

That’s how Raycaster calculates how the mouse clicks on an object.

This article demo code address