THREE.Ray 和 THREE.Raycaster 用途和功能

在 ​Three.js ​ 中,THREE.RayTHREE.Raycaster 都是与射线(Ray)相关的类,但它们的用途和功能有所不同。

例如 如图射线检测

1. THREE.Ray(射线)​

THREE.Ray 表示一条 ​3D 空间中的射线 ,由 ​起点(origin)​ ​ 和 ​方向(direction)​​ 定义。它主要用于数学计算,比如检测射线与物体的交点、计算距离等。

基本用法

javascript 复制代码
const origin = new THREE.Vector3(0, 0, 0);  // 射线起点
const direction = new THREE.Vector3(0, 0, 1).normalize();  // 射线方向(单位向量)

const ray = new THREE.Ray(origin, direction);

常用方法

方法 说明
ray.intersectBox(box, target) 计算射线与包围盒(Box3)的交点
ray.intersectPlane(plane, target) 计算射线与平面(Plane)的交点
ray.distanceToPoint(point) 计算射线到某点的最短距离
ray.closestPointToPoint(point, target) 计算射线上离某点最近的点

实战,两个点绘制箭头

csharp 复制代码
const pointer7 = pointers[0]; // 起点
      const pointer8 = pointers[1]; // 终点
      // 更新手部指针位置
      handPointer.set(pointer8.x, pointer8.y, pointer8.z);
      // 更新球体位置(可视化手指位置)
      fingerSphere.position.copy(handPointer);
      // 计算正确的射线方向(终点 - 起点,并归一化)
      const direction = new THREE.Vector3().subVectors(
        new THREE.Vector3(pointer8.x, pointer8.y, pointer8.z), // 终点
        new THREE.Vector3(pointer7.x, pointer7.y, pointer7.z)   // 起点
      ).normalize();// 注意这里的归一化
      if (handIndex == 0) {
        // 设置射线起点和方向
        rayHand1.origin.set(pointer7.x, pointer7.y, pointer7.z);
        rayHand1.direction.copy(direction);
        // 移除旧的箭头(如果存在)
        if (arrowHelper1) {
          handScene.remove(arrowHelper1);
        }
        // 创建新的箭头(方向正确)
        arrowHelper1 = new THREE.ArrowHelper(
          direction,                  // 归一化的方向向量
          rayHand1.origin,             // 起点
          arrowLen,                         // 箭头长度
          0x0000ff,                   // 颜色(黄色)
          arrowLen * 0.2,                        // 头部长度(可选)
          arrowLen * 0.04                         // 头部宽度(可选)
        );

        handScene.add(arrowHelper1);
      } else {
        // 设置射线起点和方向
        rayHand2.origin.set(pointer7.x, pointer7.y, pointer7.z);
        rayHand2.direction.copy(direction);
        // 移除旧的箭头(如果存在)
        if (arrowHelper2) {
          handScene.remove(arrowHelper2);
        }

        // 创建新的箭头(方向正确)
        arrowHelper2 = new THREE.ArrowHelper(
          direction,                  // 归一化的方向向量
          rayHand2.origin,             // 起点
          arrowLen,                         // 箭头长度
          0x0000ff,                   // 颜色(黄色)
          arrowLen * 0.2,                        // 头部长度(可选)
          arrowLen * 0.04                         // 头部宽度(可选)
        );

        handScene.add(arrowHelper2);
      }

2. THREE.Raycaster(射线投射器)​

THREE.Raycaster 是一个更高级的工具,用于 ​检测射线与 3D 场景中的物体(Mesh、Points、Line 等)的交点 。它常用于 ​鼠标拾取(点击检测)、碰撞检测、视线检测​ 等交互功能。

基本用法

javascript 复制代码
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();  // 归一化的鼠标坐标 [-1, 1]

// 更新射线(从相机位置发射到鼠标方向)
raycaster.setFromCamera(mouse, camera);

// 检测射线与场景中的物体相交
const intersects = raycaster.intersectObjects(scene.children);

if (intersects.length > 0) {
    console.log("点击了物体:", intersects[0].object);
}

常用方法

方法 说明
raycaster.set(origin, direction) 手动设置射线
raycaster.setFromCamera(coords, camera) 从相机视角发射射线(用于鼠标拾取)
raycaster.intersectObject(object, recursive) 检测射线与单个物体的交点
raycaster.intersectObjects(objects, recursive) 检测射线与多个物体的交点

示例:鼠标点击拾取物体

javascript 复制代码
window.addEventListener('click', (event) => {
    // 归一化鼠标坐标 [-1, 1]
    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);

    if (intersects.length > 0) {
        console.log("点击了:", intersects[0].object);
    }
});

3. THREE.Ray vs THREE.Raycaster

THREE.Ray THREE.Raycaster
用途 数学计算(距离、交点) 场景交互(鼠标拾取、碰撞检测)
依赖 仅依赖 THREE.Vector3 依赖 THREE.CameraTHREE.Scene
计算方式 手动计算射线与几何体的交点 自动检测射线与 3D 物体的交点
适用场景 计算射线与平面、包围盒的交点 检测鼠标点击、视线检测

4. 总结

  • THREE.Ray:用于 数学计算,如射线与几何体的交点、距离计算等。
  • THREE.Raycaster:用于 场景交互,如鼠标拾取、碰撞检测等。
  • Raycaster 内部使用了 Ray**,但提供了更高级的功能,可以直接检测 3D 物体。

如果你要做 ​鼠标交互 ​(如点击选中物体),用 ​Raycaster

如果你要做 ​数学计算 ​(如射线与平面的交点),用 ​Ray

相关推荐
YAY_tyy13 小时前
Three.js 开发实战教程(五):外部 3D 模型加载与优化实战
前端·javascript·3d·three.js
入秋1 天前
Three.js 实战之电子围栏可根据模型自动生成
前端·前端框架·three.js
答案answer2 天前
three.js着色器(Shader)实现数字孪生项目中常见的特效
前端·three.js
KallkaGo7 天前
threejs复刻原神渲染(三)
前端·webgl·three.js
刘皇叔code9 天前
如何给Three.js中ExtrudeGeometry的不同面设置不同材质
webgl·three.js
vivo互联网技术9 天前
拥抱新一代 Web 3D 引擎,Three.js 项目快速升级 Galacean 指南
前端·three.js
你真的可爱呀13 天前
5.Three.js 学习(基础+实践)
学习·three.js