javascript - 三个JS raycaster,随着鼠标移动找到交叉点

标签 javascript performance three.js

我感觉这种方法是完全错误的,因为我无法让我的网站获得适当的性能。

这是我希望您看到的主要代码:

onDocumentMouseMove( event ) {
    if ( this.isUserInteracting === true ) {
      this.lon = ( this.onMouseDownMouseX - event.clientX ) * 0.1 + this.onMouseDownLon;
      this.lat = ( event.clientY - this.onMouseDownMouseY ) * 0.1 + this.onMouseDownLat;
    }
    this.mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
    this.mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

    if( !this.state.VR ){
      this.raycaster.setFromCamera( this.mouse, this.camera );
      var intersects = this.raycaster.intersectObjects( this.indicatorHotspotPlane );

      if( intersects.length > 0 ) {
        this.actualIntersect = intersects[0];

        $('html,body').css('cursor', 'pointer');
        if(!intersects[ 0 ].object.isAction){
          this.marker.material.opacity = 1;
          this.marker.lookAt( intersects[ 0 ].face.normal );
          this.marker.position.copy( intersects[ 0 ].point );
          this.marker.position.y = this.marker.position.y + 30;
          if( intersects[ 0 ].point.x >= 0 ){
            this.marker.position.x = this.marker.position.x - 30;
          }else{
            this.marker.position.x = this.marker.position.x + 30;
          } 
        }
      } else {
        this.actualIntersect = null;
        $('html,body').css('cursor', 'move');
        this.marker.material.opacity = 0;
      }
    }
  }

我相信在这种事件处理程序中运行 raycaster.intersectObjects 是一个非常昂贵的操作。

如果我评论这段代码,一切都会运行良好。

是否有其他方法可以在鼠标移动时找到交叉点而不会出现性能问题?

this.indicatorHotspotPlane 是一个数组,其中可能有 5 个像这样的对象:

var hotspotPlane = new THREE.Mesh( new THREE.PlaneBufferGeometry( hotpot.width , hotpot.height ) );

我的场景包含这些对象和一个带有纹理的球体几何体。

最佳答案

看看this three.js example .

这里发生了什么:

  1. 使用每个形状的唯一纯色将场景渲染到离屏渲染目标。
  2. 根据渲染目标 X、Y 坐标检查鼠标坐标,并获取鼠标下方的颜色(如果有)。
  3. 根据颜色->网格图检查颜色
  4. 关联网格会更新以反射(reflect)其“突出显示”状态。
  5. 重新渲染主场景,该部分现在突出显示。

这样做仍然有成本:每次需要刷新渲染目标时,您都会产生额外的渲染。此外,如果您的场景非常大(渲染需要很长时间),它的性能可能与光线转换一样差。尽管如此,这个故事的寓意是,从缓冲区读取颜色值比执行光线转换要容易得多。

另一个需要注意的是,这仅适用于最接近的形状(相当于 intersects[0])。这是因为被遮挡的形状不会暴露其颜色(它们的颜色完全被其他形状覆盖)。因此,如果您需要获取鼠标下的所有形状,那么光线转换仍然是最佳选择。

其他信息:

我忽略了你的部分代码并直接跳到解决光线跟踪问题。经过更深入的审查后,这里有一些额外的信息:

看起来您正在获取相交的任何对象,并检查特定属性:

if(!intersects[ 0 ].object.isAction){

使用上述方法,您可以检查从颜色图中获得的任何对象上的该属性。

要获得交点,您需要执行光线转换,但现在只有当鼠标下方的对象首先通过测试时才会发生这种情况,而不是每次鼠标移动时都会发生。

当光标位于适当的对象上时,每次鼠标移动事件都会发生光线转换,因此您可能需要重新考虑需要更新标记的频率(可能每 N 帧),或者也许仅在第一次遇到特定形状时才设置标记。我不知道你的用例,所以也许这不可行。

关于javascript - 三个JS raycaster,随着鼠标移动找到交叉点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48691642/

相关文章:

javascript - 在树状 angularjs 模型中检索对象

javascript - 是否可以用普通的 Laravel 创建一个网络聊天应用程序

C++ 替换 C99 VLA(目标 : preserve performance)

javascript - 如何使用 WebVR 使 THREE.Mesh 看起来有立体感?

animation - 三个 JS 中的 Cinema 4D 动画

php - 如何...将 "plus"b 转换为 "+"b

javascript - 让 $.post 函数返回父函数中的响应

java - Android 中加载太多图片时游戏会卡住

c++ - 工作维度的重新排序可能会带来巨大的性能提升,但为什么呢?

javascript - 物体之间的碰撞问题取​​决于一个物体的速度