You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js中Raycaster检测多球体为何相交距离一致?

THREE.js Raycaster 相交距离异常问题

问题描述

我们创建了三个球体:

const object1 = new THREE.Mesh(
    new THREE.SphereGeometry(0.5, 16, 16),
    new THREE.MeshBasicMaterial({ color: '#ff0000' })
)
object1.position.x = - 2

const object2 = new THREE.Mesh(
    new THREE.SphereGeometry(0.5, 16, 16),
    new THREE.MeshBasicMaterial({ color: '#ff0000' })
)

const object3 = new THREE.Mesh(
    new THREE.SphereGeometry(0.5, 16, 16),
    new THREE.MeshBasicMaterial({ color: '#ff0000' })
)
object3.position.x = 2

同时创建了一个Raycaster:

const raycaster = new THREE.Raycaster();

const rayOrigin = new THREE.Vector3(-3, 0, 0);
const rayDirection = new THREE.Vector3(1, 0, 0);

raycaster.set(rayOrigin, rayDirection);

const intersects = raycaster.intersectObjects([object1, object2, object3])
console.log(intersects)

打印intersects数组得到如下结果:

0: {distance: 2.5, point: Vector3, object: Mesh, uv: Vector2, face: {…}, …}
1: {distance: 2.5, point: Vector3, object: Mesh, uv: Vector2, face: {…}, …}
2: {distance: 2.5, point: Vector3, object: Mesh, uv: Vector2, face: {…}, …}
length: 3

为何所有球体的相交距离都相同?按预期应该分别是0.5、2.5和4.5才对,我遗漏了什么?

问题原因与解决方法

问题核心在于你创建的Mesh对象没有更新世界矩阵:
THREE.js中,物体的局部位置(如position.x)需要通过世界矩阵(matrixWorld)转换为世界坐标,Raycaster进行相交检测时依赖的是物体的世界坐标。如果Mesh未被添加到场景,也没有手动更新世界矩阵,它的世界坐标会保持初始的(0,0,0)——也就是说三个球体实际上都处于原点位置,射线到它们的相交距离自然一致。

解决方式二选一:

  • 方式一:将Mesh添加到场景
    场景在渲染流程中会自动更新所有子物体的世界矩阵:
    scene.add(object1, object2, object3);
    
  • 方式二:手动更新世界矩阵
    如果不需要将Mesh加入场景,可手动调用方法更新每个物体的世界矩阵:
    object1.updateMatrixWorld(true);
    object2.updateMatrixWorld(true);
    object3.updateMatrixWorld(true);
    

完成上述操作后,Raycaster就能正确识别三个球体的实际位置,计算出的相交距离会符合预期:0.5、2.5、4.5。

内容的提问来源于stack exchange,提问作者Michael K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 12:25:14