如何正确销毁 Three.js 场景?(r55)

10
似乎Three.js没有一种良好的方法来处理THREE.Scene及其内部所有对象的释放。目前我正在执行以下操作:
  $.each(scene.__objects, function(idx, obj) {                               
    scene.remove(obj);                                                                                     
    if (obj.geometry) {                                                                                    
      obj.geometry.dispose();                                                                              
    }                                                                                                      
    if (obj.material) {                                                                                    
      if (obj.material instanceof THREE.MeshFaceMaterial) {                 
        $.each(obj.material.materials, function(idx, obj) {                 
          obj.dispose();                                                                                   
        });                                                                                                
      } else {                                                                                             
        obj.material.dispose();                                                                            
      }                                                                                                    
    }                                                                                                      
    if (obj.dispose) {                                                                                     
      obj.dispose();                                                                                       
    }                                                                                                      
  });             

通过查看Chrome堆剖析器,发现仍有许多对象没有被清除(纹理,着色器材料,向量等...)。


升级到r.55并查看http://mrdoob.github.com/three.js/examples/webgl_test_memory.html。 - WestLangley
我在标题中使用了错误的版本号。我现在使用的是r55版本。上面那段代码是我参考那个示例创建的。 - zfedoran
1个回答

4
我同意arriu的观点,应该有一种更加简洁和通用的方式来释放three.js中的内存,可能从场景节点开始遍历,一直到底层节点。我认为他上面的通用函数还应该扩展,以处理更多类型的内存分配。
观察示例webgl_test_memory.html,它对示例做了非常具体的事情,并在其分配后立即释放内存。查看webgl_test_memory2.html,这个示例也通过将网格添加到数组中,然后逐个处置数组的元素来做一些非常特定的事情。这种方法无法处理在函数调用中进行的许多内存分配。
我并不是说这两个示例没有释放内存。我认为场景节点应该有一个方法来释放其下方的所有内存。

有关dispose()的更新信息,请访问https://dev59.com/KFwX5IYBdhLWcg3w-Tlv#33199591。 - gaitat
它实际上不能有那个方法。如果您在两个场景中使用相同的对象怎么办?如果您切换场景但想保留对象怎么办?如果您删除网格但想保留材质怎么办?或者也许您想保留几何形状,但处理网格(也许您正在更改其材质,或出于任何原因)。在简单的示例项目中通常根本不需要这样做,但在大型、生产就绪的项目中,我每天都会遇到这种情况。您不能那么自由地做,开发人员必须明确说明什么被释放,什么不被释放。 - tfrascaroli
这是来自MrDoob的一个很好的解释:https://github.com/mrdoob/three.js/issues/5175 - tfrascaroli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接