Change color of instance mesh index on raycast

I am working on a project and need to be able to click on a instance mesh and highlight clicked cubes that make up that mesh.

Here is the project: Test - CodeSandbox

I created a this._createRayCaster method that creates a raycaster, with a event listener, that passes the intersects into a call back arguement. It should change the color of the a instanced cube index when clicked, but it does not do that. three.js docs states that this syntax for creating a color should work.

_rayCastCallback(intersects) {
    console.log("Intersects");
    console.log(intersects);
    // Do what you want with the raycasted items here
    if (intersects && intersects.length >= 1) {
      console.log("Current Instnace Id");
      console.log(intersects[0].instanceId);
      // Set its color to the path color
      intersects[0].object.setColorAt(
        intersects[0].instanceId,
        new THREE.Color(0xffff00)
      );
      // Trying to display the color
      intersects[0].object.updateMatrix();
    }
  }
  // Callback is where the interescting objects are passed into
  _createRayCaster(callback) {
    this._pointer = new THREE.Vector2();
    this._raycaster = new THREE.Raycaster();
    window.addEventListener("pointerdown", (event) => {
      // Normalize the pointer coordinates from -1 and 1
      this._pointer.x = (event.clientX / this._container.clientWidth) * 2 - 1;
      this._pointer.y = -(event.clientY / this._container.clientHeight) * 2 + 1;
      // Calculate the intersecting object using cameara position
      this._raycaster.setFromCamera(this._pointer, this._camera);
      // pass objects into callback
      callback(this._raycaster.intersectObjects(this._scene.children));
    });
  }

the code that you need is the same Instanced vertex-colors - CodeSandbox

1 Like

Instantiate blue boxes this way:

  _createDisplay() {
    const geometry = new THREE.BoxGeometry(1, 1, 1);
    const material = new THREE.MeshStandardMaterial({
      //color: 0x0f0fff
    });
    let c = new THREE.Color(0x0f0fff);
    let cubeObj = new THREE.Object3D();
    this._cubeMesh = new THREE.InstancedMesh(geometry, material, 10);
    for (let i = 0; i < 10; i++) {
      cubeObj.position.set(0, i, 0);
      cubeObj.updateMatrix();
      this._cubeMesh.setMatrixAt(i, cubeObj.matrix);
      this._cubeMesh.setColorAt(i, c); // set color individually
    }
    this._scene.add(this._cubeMesh);
    console.log(this._scene);
  }

and update the attribute with instance colors on click:

  _rayCastCallback(intersects) {
    if (intersects && intersects.length >= 1) {
      let o = intersects[0].object;
      o.setColorAt(
        intersects[0].instanceId,
        new THREE.Color(0xffff00)
      );
      o.instanceColor.needsUpdate = true; // add this line
    }
  }
1 Like

What is the difference between creating the color with a new Three color initially instead of using color: 0x0F0FFF?