Three.JS - модель GLTF загружается медленно. Как ускорить загрузку?

Я загружаю модель GLTF (9 МБ) в ThreeJS. Он определенно загружается медленно. Загрузка на мой компьютер занимает около 4-5 секунд, а на моем iPhone - около 11 секунд. Как я могу ускорить рендеринг? Мои ПК и iPhone загружают примеры с веб-сайта ThreeJS быстрее, чем мой проект. В моем проекте загружается только один объект, поэтому я чувствую, что он должен загружаться быстрее, чем примеры на веб-сайте ThreeJS.

Мой пример проекта находится здесь @ http://flowolfsworld.com/

Код

var ourObj;
var ourObj2;

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

// Optional: Provide a DRACOLoader instance to decode compressed 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();

person z Eyeland    schedule 31.08.2020    source источник
comment
Это просто ожидаемое поведение для объекта такого большого размера. 9 МБ - это большой файл для загрузки и множество вершин для декодирования и отправки в графический процессор. Примеры на Threejs.org загружаются быстро, потому что они не используют файлы размером 9 МБ. Вам следует рассмотреть возможность использования карты нормалей вместо такой плотной геометрии, например в этом примере   -  person Marquizzo    schedule 01.09.2020
comment
См. Этот веб-сайт в качестве примера: dogstudio.co Их glb файл занимает всего 840 КБ, потому что вместо моделирования меха с реальной геометрией , они использовали эту карту нормалей, чтобы сохранить сотни тысяч вершин.   -  person Marquizzo    schedule 01.09.2020


Ответы (1)


Несколько предложений по этой конкретной модели:

  1. Используйте .glb, а не .gltf. Двоичная форма glTF будет на 25-30% меньше, чем .gltf со встроенными двоичными данными, и ее не нужно декодировать из URI данных. Также можно использовать .gltf с отдельным двоичным .bin. Используйте glTF-Pipeline, чтобы внести эти изменения.
  2. Предварительно загрузите декодер Draco, вызвав dracoLoader.preload(), прежде чем ваша модель начнет загрузку. На моем тесте вашей страницы это сэкономило бы 500 мс, потраченных на загрузку декодера после того, как модель уже была загружена.
  3. Рассмотрите возможность использования https://github.com/zeux/meshoptimizer#installing-gltfpack для упростить модель или, по крайней мере, ее квантовать, а затем сжать ее. Это альтернатива Draco, которая может не так хорошо сжимать файл, но, несмотря на это, иногда может уменьшить общее время загрузки.
person Don McCurdy    schedule 31.08.2020
comment
Хорошо, спасибо. Модель .glb загрузилась намного быстрее. Предыдущая модель, которую я использовал, была gltf, но я сжал ее с помощью gltf-pipeline -i model.gltf -o modelDraco.gltf -d. Размер файла намного меньше, чем у файла .glb. Почему сжатая версия .gltf работает медленнее, чем более крупный файл .glb? - person z Eyeland; 01.09.2020
comment
И учитывая, что я переключился на предложение №1, это означает, что №2 не применяется, верно? Или я могу сжать и свой файл .glb? - person z Eyeland; 01.09.2020
comment
Хм, я заговорил слишком рано. На моем локальном компьютере он загружается почти мгновенно, но в производственной версии он по-прежнему загружается очень медленно на мобильных устройствах. Почти хуже, чем раньше. - person z Eyeland; 01.09.2020
comment
Когда я не использую сжатый файл Draco .gltf, он не отображается на мобильных устройствах. Текущее состояние кода такое же, но с добавлением файла .glb и dracoLoader.preload (). Он загружается почти мгновенно на моем локальном хосте, но совсем не загружается здесь, на моем мобильном устройстве @ flowolfsworld.com - person z Eyeland; 01.09.2020
comment
К вашему первому комментарию - вы можете сделать и то, и другое. gltf-pipeline -i model.gltf -o modelDraco.glb -d -b. Что касается ваших более поздних комментариев, я предполагаю, что исходный размер этой модели составляет около 100 МБ? Проблема в том, что все это нужно распаковать - обратно до 100 МБ - перед рендерингом. Это очень подробная геометрия с 3,5 миллионами вершин, намного больше, чем вам нужно для показываемого приложения, так что это очень медленно. Такие инструменты, как gltfpack, должны иметь возможность упростить это до 10 МБ перед добавлением сжатия Draco, уменьшив количество вершин на ~ 90%, а затем сжатие Draco сделает его еще меньше. - person Don McCurdy; 01.09.2020