【问题标题】:Three.js get's very slow after removing and creating objectsThree.js 在删除和创建对象后变得很慢
【发布时间】:2016-05-03 16:09:14
【问题描述】:

我是 three.js 的新手,我正在尝试一个非常基本的射击游戏。用户应该拍摄一个彩色的箱子(盒子)。当他这样做时,箱子消失了,另一个随机箱子出现了,依此类推。

if (intersects.length > 0) {
             intersects[0].object.material.color.setHex(Math.random() * 0xffffff);
                  scene.remove(object);
                  create_cube();
                  animate();
...

在着陆时,它工作得非常顺利。完全没有滞后。但是我射击的盒子越多,游戏就越开始滞后。

我在内存分配或垃圾收集方面做错了吗?

这是一个 JSfiddle:https://jsfiddle.net/k0s2nmru/

(虽然我的代码作为单独的页面可以正常工作,但放在 JSfiddle 中时似乎无法正常工作)

更新:

我添加了three.js 附带的统计信息。即使游戏开始滞后,它们也不断为我提供相当不错的每秒帧数(高达 150 帧或更多)。也许我没有以正确的方式实现它?

【问题讨论】:

标签: javascript performance three.js


【解决方案1】:

乍一看,我看到了 3 种优化代码的方法

1) 不要在不需要的时候调用 animate 或 render

    function onDocumentMouseDown(event) {
        var mouse3D = new THREE.Vector3();
        var raycaster = new THREE.Raycaster();
        mouse3D.normalize();
        controls.getDirection(mouse3D);
        raycaster.set(controls.getObject().position, mouse3D);
        var intersects = raycaster.intersectObjects(objects);
        if (intersects.length > 0) {
     intersects[0].object.material.color.setHex(Math.random() * 0xffffff);
          scene.remove(object);
          create_cube();
          animate();     //  DON'T DO THIS

        }
        renderer.render(scene, camera);   //  DON'T DO THIS
      }

渲染是在一个紧密的循环中完成的,由 requestAnimationFrame 控制。不仅你不需要在循环之外调用它们,而且如果你这样做,你会破坏 requestAnimationFrame 优化(循环的多个实例同时运行)

2) 始终尝试使渲染达到最佳状态。

     controls.getObject().translateX(velocity.x * delta);
     controls.getObject().translateY(velocity.y * delta);
     controls.getObject().translateZ(velocity.z * delta);

     if (controls.getObject().position.y < 10) {

为什么不使用 controls.getObject() 的结果创建一个临时变量?

3) 尽可能重复使用

在 yomotsu 的回答中,但有点不同:为什么不关闭被击中的立方体的可见性,改变它的颜色和位置,让它再次可见?

【讨论】:

  • 非常感谢!我实现了你的 3 种优化方式,现在可以流畅地运行(而且我学到了一些新东西!)。我认为 1 号的性能提升最多。换一种说法:你知道为什么统计数据一直显示不错的每秒帧数吗?我把它放在代码中的正确位置了吗?
  • 当您同时运行多个渲染时,您的帧速率甚至可能比以往更高(requestAnimationFrame 应该可以避免您在标准 PC 中达到 150fps,因为卡刷新率通常较低)但这并没有'不意味着这是有用的工作)
【解决方案2】:

当你移除一个对象时,你必须移除对象中使用的几何材质和纹理。因为资源缓存在渲染器中。

scene.remove( mesh );
// clean up
geometry.dispose();
material.dispose();
texture.dispose();

检查这个例子。 http://threejs.org/examples/#webgl_test_memory

【讨论】:

  • 感谢您的回复。在检测到点击后尝试将scene.remove( object ); geometrycube3.dispose(); materialcube3.dispose(); 添加到我的代码中,但它似乎无法解决延迟问题。难道我做错了什么?没有使用texture.dispose();,因为我的盒子没有纹理,只有颜色。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-06
  • 2018-03-30
  • 1970-01-01
  • 2012-04-23
  • 2011-04-25
  • 2012-07-25
  • 1970-01-01
相关资源
最近更新 更多