返回

ThreeJS光线投射(Raycaster)计算鼠标点击物体(拾取)

前端

在三维空间中计算鼠标点击了哪个物体,其实就是从点击的那个点开始发出一条射线,看这条线穿过了哪些物体。 在此之前先来熟悉一下三维空间的坐标系,在threeJs中使用的是右手坐标系,屏幕的中心点为原点。坐标轴的正方向分别指向屏幕的右方、上方和前方。

为了使用Raycaster,首先需要创建一个Raycaster对象。这个对象可以重用,不需要每次使用时都创建新的。

const raycaster = new THREE.Raycaster();

接下来,我们需要设置射线的方向。射线的方向是通过一个原点和一个方向向量来定义的。原点是射线发出的点,方向向量是射线的方向。

const mouse = new THREE.Vector2();
const raycaster.setFromCamera( mouse, camera );

这里,mouse是鼠标点击的屏幕坐标,camera是当前的相机。setFromCamera()方法会根据鼠标点击的屏幕坐标和相机的位置来计算出射线的方向。

现在,就可以使用raycaster对象来检测射线穿过的物体了。

const intersects = raycaster.intersectObjects( scene.children, true );

intersectObjects()方法会返回一个数组,其中包含了射线穿过的所有物体。每个元素都是一个Intersection对象,包含了射线与物体的交点信息。

通过遍历intersects数组,就可以获取到鼠标点击的物体。

if ( intersects.length > 0 ) {

    const object = intersects[ 0 ].object;

}

还可以使用Raycaster来检测射线是否与物体相交,而不需要返回交点信息。

const intersects = raycaster.intersectObjects( scene.children, true );

if ( intersects.length > 0 ) {

    // 射线与物体相交

} else {

    // 射线没有与物体相交

}

示例

以下是一个示例,展示了如何使用Raycaster来计算鼠标点击了哪个物体。

<!DOCTYPE html>
<html>
<head>
  
  <script src="three.js"></script>
</head>
<body>
  <canvas id="myCanvas"></canvas>

  <script>
    // 创建场景
    const scene = new THREE.Scene();

    // 创建相机
    const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
    camera.position.z = 5;

    // 创建渲染器
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );

    // 创建一个立方体
    const geometry = new THREE.BoxGeometry( 1, 1, 1 );
    const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
    const cube = new THREE.Mesh( geometry, material );
    scene.add( cube );

    // 创建一个射线投射器
    const raycaster = new THREE.Raycaster();

    // 监听鼠标点击事件
    window.addEventListener( 'click', ( event ) => {

      // 获取鼠标点击的屏幕坐标
      const mouse = new THREE.Vector2();
      mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
      mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

      // 设置射线的方向
      raycaster.setFromCamera( mouse, camera );

      // 检测射线与物体的交点
      const intersects = raycaster.intersectObjects( scene.children, true );

      if ( intersects.length > 0 ) {

        // 射线与物体相交

        // 获取鼠标点击的物体
        const object = intersects[ 0 ].object;

        // 改变物体的颜色
        object.material.color.set( 0xff0000 );

      }

    } );

    // 渲染场景
    function animate() {

      requestAnimationFrame( animate );

      renderer.render( scene, camera );

    }

    animate();
  </script>
</body>
</html>

在上面的示例中,当鼠标点击屏幕时,射线投射器会计算出射线的方向。然后,射线投射器会检测射线与场景中物体的交点。如果射线与物体相交,则会改变物体的颜色。

总结

Raycaster类是一个强大的工具,可以用来检测射线与物体的交点。这可以用于拾取物体、进行交互操作等。希望本文能帮助你了解Raycaster类的用法。