• three.js中射线对性能的影响


    本篇内容采集自多平台汇集而成

    不要在每一帧上进行光线投射,而是应该在间隔上进行光线投射。您可以使用setTimeoutorsetInterval或检查更新循环中的时间。

    onUpdate() {
       // Code that runs once per frame
    
       // Check that we've waited long enough to raycast
       if (Date.now() - this.lastRaycast > this.raycastInterval && this.qRaycast) {
           this.handleRaycast();
           this.lastRaycast = Date.now();
           this.qRaycast = false;
       }
      requestAnimationFrame( () => this.onUpdate() );
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    我也只在鼠标移动时排队光线投射(如果鼠标不移动,没有理由继续光线投射),并且因为我在我的项目中有平移,所以我在平移运动期间禁用光线投射,以防止在移动过程中出现任何抖动。

    // Event Handlers
    // Record mouse position for raycast
    onMouseMove(e) {
       this.mouse.x = (e.clientX / window.innerWidth ) * 2 - 1;
       this.mouse.y = -((e.clientY - 50) / window.innerHeight ) * 2 + 1;
    
       // If we are panning, don't queue a raycast
       this.qRaycast = !this.mouseState.held;
    }
    
    // My app has panning, and we don't wanna keep raycasting during pan
    onMouseDown(e) {
       this.mouseState.lastClick = Date.now();
       this.mouseState.clicked = false;
       this.mouseState.held = true;
    }
    
    onMouseUp(e) {
       this.mouseState.held = false;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    然后我们处理光线投射:

    // Like lasers, but virtual.
    handleRaycast() {
       let hits = null;
       let hitcount = 0;
       if (UI.raycast && meshObj) {
           this.raygun.setFromCamera(this.mouse, this.camera);
           hits = this.raygun.intersectObject(meshObj, false);
           hitcount = hits.length;
       }
    
       if (hitcount > 0) {
           // Do stuff with the raycast here
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    如果您仍然遇到性能问题,那么您可能需要考虑分解该循环函数,以便在 XXms 之后它会中断以让 UI 更新,然后在下一帧继续更新

    我想证明这一点,光线投射不是很贵,但前提是你愿意这么做。默认值为threejs实现是O(n)复杂的,n是网格中的面数。不过,您可以通过空间索引将其降到O(log(n)),这突然使其几乎免费。
    我通常每帧运行100次左右的光线投射,没有明显的性能影响。所以答案是-这取决于🤷‍♀

    为了保持便宜,请尽量确保边界框(或球体)检查尽可能有效。如果光线总是在某个地方与网格相交,那么将光线投射到具有 100K 个顶点的单个大型世界网格中将会很昂贵。对具有 1K 个顶点的 100 个网格进行射线投射会便宜得多,因为大多数网格将通过简单的边界框检查被消除。

    Raycasting 不是正确的解决方案——如果对象的边界框完全穿过光线,那么 Raycaster 将遍历网格中的每个三角形。如果您想知道光线与球体的交点,使用起来会快得多Ray.intersectSphere 13获取交点坐标。
    如果您需要一个特定的三角形,而不是特定的坐标,那么您可能需要某种空间数据结构而不是光线投射。

    参考
    光线投射有多贵?
    使用raycaster时的性能问题
    光线投射器的three.js 性能不佳

  • 相关阅读:
    js 关于 replace 取值、替换第几个匹配项
    UDP端口连通性检查
    python面向对象进阶-继承、多态
    c语言字符串相关函数的分析
    Dubbo3应用开发——架构的演变过程
    Android HAL机制的深入理解及在Linux上移植和运行的一个好玩的HAL小例子
    Android Studio开发入门教程:如何更改APP的图标?
    JSON基本使用
    yolo系列模型训练数据集全流程制作方法(附数据增强代码)
    机器学习中的集成学习
  • 原文地址:https://blog.csdn.net/printf_hello/article/details/126185422