1
votes

The three.js Raycaster example shows how to highlight objects using intersectObjects:

var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();

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

function render() {
    raycaster.setFromCamera( mouse, camera );
    var intersects = raycaster.intersectObjects( scene.children );
    for ( var i = 0; i < intersects.length; i++ ) {
        intersects[ i ].object.material.color.set( 0xff0000 );
    }
    renderer.render( scene, camera );
}

window.addEventListener( 'mousemove', onMouseMove, false );
window.requestAnimationFrame(render);

https://threejs.org/docs/#api/en/core/Raycaster

However this intersects objects even if they are obscured behind another object. I've created a demo showing that you can highlight objects even if they are behind the sphere object:

https://codepen.io/kmturley/pen/gObgKee

Notice how in the demo you can highlight objects behind the sphere. How can we ignore objects which are obscured by other objects? even if they exist within the Camera Frustrum and are rendered by Three.js?

My use-case is that I actually want to hide the objects which are at the back of the sphere and their labels.

Examples showing intersections:

1

1 Answers

0
votes

So actually was a very simple solve. intersectObjects actually returns Objects back in order of distance from the camera:

var intersects = raycaster.intersectObjects(points);

So by picking the first item in the array, you will always get the closest Object:

console.log(intersects[0].object);

The other thing I had to change was to include the Sphere in intersectObjects list, to ensure it would get picked before anything behind it:

var points = [];
var geometry = new THREE.SphereGeometry(radius, 20, 20);
var material = new THREE.MeshBasicMaterial({color: 0xffffff, opacity: 0.2, transparent: true});
sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);
points.push(sphere);

So intersectObjects includes the sphere, but then I ignore it as a selected Object in the following if statement:

var intersects = raycaster.intersectObjects(points);
if (intersects[0] && intersects[0].object !== sphere) {
  selected = intersects[0].object;
  selected.currentHex = selected.material.color.getHex();
  selected.material.color.setHex(0xffffff);
}

This demo now blocks objects which are behind the Sphere:

https://codepen.io/kmturley/pen/gObgKee