Three.js学习笔记(二)解决raycaster射线拾取精度问题&探究部分源码

才想起来自己还有个csdn账号需要维护,顺手记录一下最近在写three.js中踩到的坑。

在 Three.js 中,射线拾取(raycasting)是一种用于检测用户鼠标与三维场景中的对象交互的方法。这在实现鼠标点击选择、碰撞检测或交互式功能时非常有用。

其原理图大概如下所示:

当我们在用射线拾取three.js中的物体时,往往会遇到拾取精度问题

1、画布大小为适配

2、需要设置与各种物体相交时的精度因子

第1个问题比较好解决,以下代码就可以解决问题了

const getRayIntersectsAction = (boxNode, intersectObjects, event) => {
    let getBoundingClientRect = boxNode.getBoundingClientRect();
    mouse.x = ((event.clientX - getBoundingClientRect.left) / boxNode.offsetWidth) * 2 - 1;
    mouse.y = - ((event.clientY - getBoundingClientRect.top) / boxNode.offsetHeight) * 2 + 1;

    raycaster.setFromCamera(mouse, camera);
    return raycaster.intersectObjects(intersectObjects, true);
  }

而最近工作中我遇到了第二个问题。拾取线段精度不准确。

具体就是在遇到渲染Line2或者LineSegements2后拾取有精度差,此时根据网上资料搜到的设置

linePrecision并不能解决问题。

笔者用到LineSegements2是因为需要渲染大量不连续的线段,而LineSegements2虽然和LineSegements只差一个字,实现的方法大大不同,LineSegements继承了Line,而Line2则是继承了LineSegements2,在webgl的渲染中,为了渲染带宽度的线段,往往会选择Line2。

three.js提供的两种线,Line 和 Line2 有所区别。前者只支持宽度为1的线,后者则支持任意线宽。

按照官方示例,可以很容易绘制出已确定顶点位置的线要素(静态的线)

然而很多时候我们都需要动态的往线要素里添加新的顶点,网上查了很多资料,大体思路都是构造新的几何体(LineGeometry)替换已有线对象的几何体,然后重新设置点位(line.geometry = new LineGeometry(); line.geometry.setPositions(positions););或是移除原有的线,然后构造新的线对象。这两种方式原理相似,如果在频繁加入顶点的情况下,会造成明显的性能问题。

LineSegements2本质上都是BufferGeometry用实例化的方式渲染。使用three.js绘制不连续的线段重要的其实是使用LineSegmentsGeometry,然后使用setPositions,setColors的方式去渲染着色。如果使用了LineSegements2,使用射线拾取时,精度问题很大,看源码可以发现

影响拾取精度的竟然是raycaster.params.Line2.threshold的值!当你没设置时为0!!

接下来只要修改raycaster.params.Line2.threshold = 1或者合适的值即可。不同的几何体最好阅读其源码去设置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值