使用 Three.js 加载多个 obj+mtl 会崩溃,尤其是在 iOS 上

Multiple obj+mtl loading with Three.js crashes especially on iOS

我想使用 Three.js 和以下代码加载多个 obj+mtl 文件。它适用于一个或两个 obj 数据。但是当我尝试加载多个 OBJ(超过三个)时,它会崩溃,尤其是在 iOS.

obj数据较小,一共6MB。如果我在加载后克隆该对象,它甚至可以处理十个对象,但如果在 iOS 上多次使用 THREE.OBJMTLLoader,它就会崩溃。

我找不到加载多个 obj 文件的好例子。对于多个 OBJ,有什么我应该关心的吗?

<!DOCTYPE html>
<html lang="ja">
  <head><meta charset="UTF-8"></head>
  <script src="http://threejs.org/build/three.min.js"></script>
  <script src="http://threejs.org/examples/js/loaders/MTLLoader.js"></script>
  <script src="http://threejs.org/examples/js/loaders/OBJMTLLoader.js"></script>
  <body>
<div id="canvas_frame"></div>
    <script>
    var canvasFrame, scene, renderer, camera;
    
    canvasFrame = document.getElementById('canvas_frame');
    renderer = new THREE.WebGLRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );
    canvasFrame.appendChild( renderer.domElement );
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
    camera.position.set(50,50,50);
    camera.lookAt( {x: 0, y: 0, z: 0} );
    var ambient = new THREE.AmbientLight(0xFFFFFF);
    scene.add(ambient);

    function animate() {
        renderer.render( scene, camera );
        requestAnimationFrame( animate );
    }

    function loadObjMtl(objUrl, mtlUrl, url, x, y, z){
          var loader = new THREE.OBJMTLLoader();
          loader.crossOrigin = 'anonymous';
          loader.load( objUrl, mtlUrl,
              function ( object ) {
                object.url = url; 
                object.position.set(x,y,z);
                scene.add ( object ); 
            });
    }

    objUrl = "http://test2.psychic-vr-lab.com/temp/mesh_reduced.obj";
    mtlUrl = "http://test2.psychic-vr-lab.com/temp/mesh_reduced.mtl";
    loadObjMtl(objUrl,mtlUrl,"",0,0,0);
    loadObjMtl(objUrl,mtlUrl,"",20,20,0);
    loadObjMtl(objUrl,mtlUrl,"",40,20,0);
    loadObjMtl(objUrl,mtlUrl,"",60,0,0);
    animate(); 
    </script>

  </body>
</html>

您的 iOS 设备上的显存可能 运行 不足。

您使用的纹理文件很大,例如这个是 4096x4096 http://test2.psychic-vr-lab.com/temp/tex_0.jpg

未压缩为供 OpenGL 使用的原始位图,然后占用大量内存(我认为是数十兆,RGB 的 4096 * 4096 * 3 大约为 50MB)。

使用较小分辨率的图片。并且另外使用可以在压缩格式中使用的纹理格式,在 iOS PVRTC 上,在 https://github.com/mrdoob/three.js/pull/5337 ("PVRTC support in examples")[=12 中添加了对 three.js 的支持=]

克隆之所以有效,是因为您可以为许多对象重复使用相同的纹理 -- 大图像仅在内存中出现一次。如果他们都使用相同的图像,那当然是您想要的。但是,如果您需要为各种对象使用不同的图像,那么您需要减少它们的内存消耗。