最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Three.JS - GLTF model loads slow. How to speed up load time? - Stack Overflow

programmeradmin1浏览0评论

Im loading a GLTF model (9mb) into ThreeJS. It's definitely loading slow. It takes about 4-5 seconds to load on my PC and about 11 seconds to load on my IPhone. How can i speed up the rendering times? My PC and IPhone load examples from the ThreeJS website faster than my project. My project has only one object being loaded so I feel like it should load faster than the examples on ThreeJS website.

My example project is located here @ /

Code

var ourObj;
var ourObj2;

// Instantiate a loader
var loader = new THREE.GLTFLoader();

// Optional: Provide a DRACOLoader instance to decode pressed mesh data
var dracoLoader = new THREE.DRACOLoader();
dracoLoader.setDecoderPath( '/js/draco/' );
loader.setDRACOLoader( dracoLoader );



let scene, camera, renderer, stars, starGeo;

function init() {

  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
  camera.position.z = 25;

  //renderer = new THREE.WebGLRenderer();
 renderer = new THREE.WebGLRenderer();
  renderer.setClearColor("#000000");
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  starGeo = new THREE.Geometry();
  for(let i=0;i<6000;i++) {
    star = new THREE.Vector3(
      Math.random() * 600 - 300,
      Math.random() * 600 - 300,
      Math.random() * 600 - 300
    );
    star.velocity = 0;
    star.acceleration = 0.02;
    starGeo.vertices.push(star);
  }

  let sprite = new THREE.TextureLoader().load( 'star.png' );
  let starMaterial = new THREE.PointsMaterial({
    color: 0xaaaaaa,
    size: 0.7,
    map: sprite
  });

  stars = new THREE.Points(starGeo,starMaterial);
  scene.add(stars);

 // window.addEventListener("resize", onWindowResize, false);
  var hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444 );
  hemiLight.position.set( 0, 300, 0 );
  scene.add( hemiLight );
  
  var dirLight = new THREE.DirectionalLight( 0xffffff );
  dirLight.position.set( 75, 300, -75 );
  scene.add( dirLight );



  loader.load(
    // resource URL
    'objs/dracowolf.gltf',
    // called when the resource is loaded
    function ( gltf ) {
  
      scene.add( gltf.scene );
      ourObj = gltf.scene;
      animate();
  
    },
    // called while loading is progressing
    function ( xhr ) {
  
      console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
  
    },
    // called when loading has errors
    function ( error ) {
  
      console.log( 'An error happened' );
  
    }
  );

  
}



function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
  }


  
function animate() {


  requestAnimationFrame(animate);
  renderer.render(scene, camera);

  if(ourObj){
        ourObj.rotation.y -= .01;
    }
  starGeo.vertices.forEach(p => {
    p.velocity += p.acceleration
    p.y -= p.velocity;
    
    if (p.y < -200) {
      p.y = 200;
      p.velocity = 0;
    }
  });
  starGeo.verticesNeedUpdate = true;
  stars.rotation.y +=0.002;

}
init();

Im loading a GLTF model (9mb) into ThreeJS. It's definitely loading slow. It takes about 4-5 seconds to load on my PC and about 11 seconds to load on my IPhone. How can i speed up the rendering times? My PC and IPhone load examples from the ThreeJS website faster than my project. My project has only one object being loaded so I feel like it should load faster than the examples on ThreeJS website.

My example project is located here @ http://flowolfsworld./

Code

var ourObj;
var ourObj2;

// Instantiate a loader
var loader = new THREE.GLTFLoader();

// Optional: Provide a DRACOLoader instance to decode pressed mesh data
var dracoLoader = new THREE.DRACOLoader();
dracoLoader.setDecoderPath( '/js/draco/' );
loader.setDRACOLoader( dracoLoader );



let scene, camera, renderer, stars, starGeo;

function init() {

  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
  camera.position.z = 25;

  //renderer = new THREE.WebGLRenderer();
 renderer = new THREE.WebGLRenderer();
  renderer.setClearColor("#000000");
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  starGeo = new THREE.Geometry();
  for(let i=0;i<6000;i++) {
    star = new THREE.Vector3(
      Math.random() * 600 - 300,
      Math.random() * 600 - 300,
      Math.random() * 600 - 300
    );
    star.velocity = 0;
    star.acceleration = 0.02;
    starGeo.vertices.push(star);
  }

  let sprite = new THREE.TextureLoader().load( 'star.png' );
  let starMaterial = new THREE.PointsMaterial({
    color: 0xaaaaaa,
    size: 0.7,
    map: sprite
  });

  stars = new THREE.Points(starGeo,starMaterial);
  scene.add(stars);

 // window.addEventListener("resize", onWindowResize, false);
  var hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444 );
  hemiLight.position.set( 0, 300, 0 );
  scene.add( hemiLight );
  
  var dirLight = new THREE.DirectionalLight( 0xffffff );
  dirLight.position.set( 75, 300, -75 );
  scene.add( dirLight );



  loader.load(
    // resource URL
    'objs/dracowolf.gltf',
    // called when the resource is loaded
    function ( gltf ) {
  
      scene.add( gltf.scene );
      ourObj = gltf.scene;
      animate();
  
    },
    // called while loading is progressing
    function ( xhr ) {
  
      console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
  
    },
    // called when loading has errors
    function ( error ) {
  
      console.log( 'An error happened' );
  
    }
  );

  
}



function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
  }


  
function animate() {


  requestAnimationFrame(animate);
  renderer.render(scene, camera);

  if(ourObj){
        ourObj.rotation.y -= .01;
    }
  starGeo.vertices.forEach(p => {
    p.velocity += p.acceleration
    p.y -= p.velocity;
    
    if (p.y < -200) {
      p.y = 200;
      p.velocity = 0;
    }
  });
  starGeo.verticesNeedUpdate = true;
  stars.rotation.y +=0.002;

}
init();
Share Improve this question edited Sep 1, 2020 at 1:07 user128511 asked Aug 31, 2020 at 22:30 sirshakirsirshakir 1394 silver badges14 bronze badges 2
  • This is just the expected behavior for an object of such a large size. 9MB is a big file to download, and a lot of vertices to decode and send to GPU. The examples on Threejs load fast because they don't use 9MB files. You should look into using a normal map instead of such dense geometry, like this example – M - Commented Aug 31, 2020 at 23:18
  • See this website as an example: dogstudio.co Their glb file is only 840KB because instead of modeling the fur with real geometry, they used this normal map to save hundreds of thousands of vertices. – M - Commented Aug 31, 2020 at 23:55
Add a ment  | 

1 Answer 1

Reset to default 7

A few suggestions on this particular model:

  1. Use .glb, not .gltf. The binary form of glTF will be 25-30% smaller than a .gltf with embedded binary data, and doesn't have to be decoded from a Data URI. Using .gltf with a separate binary .bin is also an option. Use glTF-Pipeline to make these changes.
  2. Preload the Draco decoder by calling dracoLoader.preload() before your model starts loading. On my test of your page, that would save 500ms spent fetching the decoder after the model has already been downloaded.
  3. Consider using https://github./zeux/meshoptimizer#installing-gltfpack to simplify the model, or at least to quantize it, and then gzip it. This is an alternative to Draco, and may not press the file quite as well, but can sometimes decrease overall loading time despite that.
发布评论

评论列表(0)

  1. 暂无评论