Three.js使用raycaster intersectObjects忽略了被遮挡的对象

时间:2019-12-18 20:55:21

标签: javascript three.js 3d

Three.js Raycaster示例演示如何使用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

但是,即使对象在另一个对象后面被遮挡,它也会与这些对象相交。我创建了一个演示,展示了您可以突出显示对象,即使它们位于球形对象的后面:

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

请注意,在演示中如何突出显示球体后面的对象。 我们如何忽略被其他对象遮挡的对象?,即使它们存在于“摄像机视锥”中并由Three.js渲染?

我的用例是我实际上想隐藏球体后面的对象及其标签。

显示相交的示例:

1 个答案:

答案 0 :(得分:0)

所以实际上是一个非常简单的解决方案。 intersectObjects实际上会按照距相机的距离顺序返回对象:

var intersects = raycaster.intersectObjects(points);

因此,通过选择数组中的第一项,您将始终获得最接近的对象:

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

我不得不更改的另一件事是将Sphere包含在intersectObjects列表中,以确保在它后面的任何东西之前都将其选中:

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);

因此,intersectObjects包含该球体,但随后在以下if语句中将其作为选定的对象忽略了

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);
}

此演示现在可以阻止Sphere后面的对象:

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