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.
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 and 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 onaddEventListener
, please follow this link.
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.
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,
onMouseMove
function which will be called whenever our event listener captures the cursor moving on the application screen.event.clientX
and event.clientY
are being used to get the plain and coordinates of the mouse. They are then normalized between -1 and 1.Raycaster
relative to the camera’s position and passing it the coordinates of the mouse, which are contained in pointer
.intersects
keyword contains the array of objects being intersected by the ray.for
loop goes over the length of the intersects
array, and we print the objects being intersected using console.log
.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.
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.