Three.js中Raycaster射线拾取点或线模型时,碰撞范围过小无法精确检测到物体,对于精度问题相关设置

在Three.js中,Raycaster是用于检测场景中物体相交的类。当我们使用Raycaster检测物体相交时,可能会出现准确性的问题,特别是当检测到的对象是点模型或线模型时。这是因为点、线段本身并没有任何厚度,所以它的碰撞面积很小,从而导致可能无法准确地检测到物体的相交

Line线模型解决方案(当然通用 LineLoop 和 LineSegments)

Raycaster.linePrecision,linePrecision属性是一个可选属性,类型为浮点数,默认值为1。它表示在计算射线和线段相交时,额外添加的线段厚度。当我们设置该属性的值时,它将会以单位长度为线段的厚度,并将其添加到线段的两侧,以扩大检测范围。该值越小,检测范围越小,可能会出现未检测到相交的情况;该值越大,则检测范围越大,但可能出现误检的情况。所以需要在具体应用时进行合理的设置。

const geometry = new THREE.BoxGeometry(100, 100, 100)
const material = new THREE.LineBasicMaterial({color: 0xff0000})
const line = new THREE.Line(geometry, material)
const raycaster = new THREE.Raycaster()
raycaster.linePrecision = 3 // 默认值为1,越大越容易选中线模型
const intersects = raycaster.intersectObjects([line, line2, line3])

 Points点模型解决方案

Raycaster.params.Points.thresholdparams属性可以用来获取或设置Raycaster的属性值。其中,params.Points.threshold属性是一个可选属性,类型为浮点数,默认值为1。它表示在检测到模型的顶点集合是一个点云(PointCloud)时,Raycaster检测器所使用的精度(即点与光线相交判定的距离)阈值。当我们使用Raycaster检测点云时,这个 threshold 属性将会影响到 Raycaster 的路径长度判断,从而影响到最近像素上准确的点精度。如果一个点与光线的距离小于这个属性的值,那么这个点将会被视为相交点并被返回到 intersects 中

需要注意的是,当检测精度过低(threshold值设置过小)的时候,可能会出现点被忽略掉的情况,而当精度过高时(threshold值设置过大),又可能出现检测到无关点的情况。

 

 

 

const geometry = new THREE.BoxGeometry(100, 100, 100)
const material = new THREE.PointsMaterial({color: 0xff0000, size: 10.0})
const points = new THREE.Points(geometry, material)
const raycaster = new THREE.Raycaster()
raycaster.params.Points.threshold = 5.0
const intersects = raycaster.intersectObjects([points])

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Three.js ,你可以使用射线Raycaster)来进行碰撞检测射线是一个具有起和方向的线段,你可以投射它来检测它与场景物体是否相交。下面是一个实现射线碰撞检测的简单示例代码: 首先,你需要创建一个射线对象,指定其起和方向。例如: ```javascript const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2(); // 设置鼠标的坐标范围为[-1, 1] function onMouseMove(event) { mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; } // 在每一帧更新射线的起和方向 function animate() { raycaster.setFromCamera(mouse, camera); renderer.render(scene, camera); requestAnimationFrame(animate); } ``` 接下来,在场景物体上添加可选的碰撞检测标记(例如,设置物体的 `userData` 属性或添加自定义属性)。例如,你可以给立方体对象添加 `userData` 属性: ```javascript const cube = new THREE.Mesh(geometry, material); cube.userData.isInteractable = true; scene.add(cube); ``` 然后,在适当的机(例如鼠标击事件)调用射线的 `intersectObjects` 方法来检测射线与场景物体是否相交。例如: ```javascript function onMouseClick() { // 计算射线与场景的所有物体的相交 const intersects = raycaster.intersectObjects(scene.children); if (intersects.length > 0) { // 获取第一个相交物体 const targetObject = intersects[0].object; if (targetObject.userData.isInteractable) { // 针对相交物体进行操作 // 例如,你可以改变物体的颜色或执行其他交互操作 targetObject.material.color.set(0xff0000); } } } ``` 这只是一个简单的示例,你可以根据自己的需求进行适当的修改和扩展。射线碰撞检测Three.js 非常强大且灵活,你可以使用它来实现各种交互和游戏功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山楂树の

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值