Three.js Mesh to Inherit Color from in-front objects

205 views Asked by At

Scenario

I'm trying to get meshes to inherit color from other meshes that are in physically in front

example:

Mesh A       Mesh B       Camera
(white)       (red)

              +---+         |\
  []          |   |      << | ]
              +---+         |/

I don't want Mesh B to be visible at all BUT I want Mesh A to be red where Mesh B would be blocking the view of Mesh A. All I can think of is that this is a kind of color overlay.

Prototype

I made a three.js prototype where two planes are partially blocking the view of a white sphere. I want to be able to turn the plans into a color overlay so that the sphere shows red, white, and blue (accidental usa flag colors)

Question

Is there a way to do this with THREE? I'm not fixed to this way of doing things but it seems possible, I just haven't come across the right documentation yet.

2

There are 2 answers

1
M - On

You could set the blending mode of each plane's material to blending: THREE.MultiplyBlending, so the plane's color is multiplied with items behind it.

See it in action here.

However, if you want it to apply to only the parts where the plane and the sphere overlap, you'd need to write a custom post-processing pass that knocks out the background. Or you could set the background color to #000, since multiplying any color by black yields black.

0
Ibrahim W. On

check the fiddle solutionLink, the two red and blue planes are invisible, a raycaster is shooting from the camera to the scene, when the red or blue planes are hit and the sphere is hit too I change the color of the ball

const raycaster = new THREE.Raycaster();
const redMat = new THREE.MeshBasicMaterial({color: 'red'});
const blueMat = new THREE.MeshBasicMaterial({color: 'blue'});
function raycastFromCameraAndUpdateSphereColor() { // place this in the render loop
    raycaster.setFromCamera( new THREE.Vector2(), camera );
    const intersects = raycaster.intersectObjects( scene.children );
    if (intersects.length > 1) {
      // name the object to identify it
      if (intersects[0].object.name === 'redPlane') {
      intersects[1].object.material = redMat;
      }
      // name the object to identify it
      if (intersects[0].object.name === 'bluePlane') {
      intersects[1].object.material = blueMat;
      }
    }
}