0
votes

I want to load multiple obj+mtl files using Three.js with the following code. It works OK with one or two obj data. But when I try to load multiple OBJs (more than three), it crashes especially on iOS.

The obj data is small, which is 6MB in total. If I clone the object after loading, it works even with ten objects, but it crashes if use THREE.OBJMTLLoader multiple times on iOS.

I couldn't find good example which load multiple obj files. Is there anything I should care about for multiple OBJs?

<!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>
1

1 Answers

0
votes

You probably run out of graphics memory on your iOS device.

The texture files you use are big, this for example is 4096x4096 http://test2.psychic-vr-lab.com/temp/tex_0.jpg

That is uncompressed to a raw bitmap for OpenGL use and takes a lot of memory then (tens of megs I think, 4096 * 4096 * 3 for RGB would be about 50MB).

Use a smaller resolution image. And additionally use a texture format which you can use in the compressed format, on iOS PVRTC, for which support to three.js was added in https://github.com/mrdoob/three.js/pull/5337 ("PVRTC support in examples")

Cloning works because you then reuse the same texture for many objects -- the big image is in memory only once. That's of course what you want if they all use the same image. But if you need different images for the various objects then you need to make their mem consumption smaller.