Using raycaster with multiple elements example


I’m currently using the threejs multiple elements example (here) to display two point clouds. I wanted to implement an onClick function where if one of the points is selected, it changes its colour. I’m quite new to threejs and so I’m a bit confused as to how the mouse coordinates should be computed for the raycaster to work. I’ve tried some suggestions (e.g. this SO post ) but don’t understand the logic enough to apply it to this situation.

Here is what I have so far, but when I click on one of the points, seemingly random points change colour.

var canvasPosition = renderer.domElement.getBoundingClientRect();
pointer.x = ((event.clientX - canvasPosition.left) / window.innerWidth) * 2 - 1;
pointer.y =  -(((event.clientY - / window.innerHeight) * 2 - 1);

raycaster.setFromCamera(pointer, scenes[0];
var hits = raycaster.intersectObject(points, false);

Any help would be much appreciated.


Hi @kw3rti!
Raycaster is a very useful tool and it uses the NDC](Device Coordinate - an overview | ScienceDirect Topics) to calculate the coordinates of pointer in 3D scene. Read attached article and you will be much richer in computers graphic knowledge.

You can find working examples in the three.js documentation (example), but the example code is indeed complicated.
Here is a snippet of mine that should clarify things for you:

let intersectObject = null;
let previousIntersectColor = null;
let newIntersectObjectColor = 0xffffff;

let raycaster = new Raycaster();

let mouse = {
    x: null,
    y: null,

pointerMoveEvent(event) {
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

    // This is used with conditional rendering, if you don't have one, just put this to your render function.
    raycaster.setFromCamera(mouse, defaultCamera);

    const intersects = this.raycaster.intersectObjects(scene.children);
    const intersect = intersects.length && intersects[0];
    if (intersect && intersect.object instanceof Mesh) {
        const { object } = intersect;
        intersectObject = object;
    } else {
        intersectObject = null;

pointerDownEvent() {
    if (intersectObject) {
        const { material } = intersectObject;
        material.color = new Color(newIntersectObjectColor);

Always remember to add objects as a argument to raycaster. This may sound obvious, but once you group your objects (using Group) you may find yourself in trouble.

Thanks for sending the link. I think I now understand the general gist - that we’re trying to convert the mouse coordinates into a normalised -1 to 1 NDC coordinate space. I think I’m just a bit thrown because the multiple elements example incorporates the scene within a div element. So do I need to take into account the offset of the frame here, and if so, how would I do that?

It’s not a one 3D Scene that is being created on that page. All of these little frames are three.js scenes, so each one of these has Raycaster initiated only for it. Besides that, I believe that it doesn’t use the Raycaster at all, it uses OrbitControls instead. Remember to always check the source code on the example page to get detailed insight to the code. :slight_smile: