2016-10-02 2 views
0

THREE.TextureLoader() ведет себя непредсказуемым и ошибочным способом. Функция load() класса пытается/загружает одни и те же активы несколько раз (т. Е. 20 раз или более).THREE.TextureLoader() загружает одну и ту же текстуру несколько раз (т. Е. 20 раз или более)

Ниже на рисунке показано это поведение с помощью консоли браузера:

enter image description here

Код, используемый для загрузки и использования текстур следует в следующем:

Element.prototype.createShaderMaterial = function (uniforms, vertexShader, fragmentShader) { 
    var loader = new THREE.TextureLoader(); 
    uniforms.texture.value = loader.load(this.texture); 

    return new THREE.ShaderMaterial({ 
     uniforms: uniforms, 
     vertexShader: vertexShader, 
     fragmentShader: fragmentShader, 
     wireframe: true 
    }); 
}; 

Вы также можете найти предварительный просмотр здесь: https://alexprut.github.io/earth-defender/ и код игры здесь: https://github.com/alexprut/earth-defender/tree/master/client/js

Что делается неправильно? Почему одно и то же изображение загружается несколько раз?

ответ

0

Дело в том, что THREE.TextureLoader() не кэшируют по умолчанию текстуры, но я думаю, что это должно или, по крайней мере, спросить вас, не делать этого. Это означает, что если у вас 400 объектов с одинаковой текстурой, библиотека сделает 400 HTTP-запросов для тех же активов.

Ниже простое решение (Singleton шаблон шаблон/Module) модуль кэш:

var TextureLoader = (function() { 
    var _instance = null; 

    var Loader = function() { 
     var _loader = new THREE.TextureLoader(); 
     var _cache = []; 

     function _cachePush(elem, val) { 
      _cache.push({ 
       element: elem, 
       value: val 
      }); 
     } 

     function _cacheSearch(elem) { 
      for (var i = 0; i < _cache.length; i++) { 
       if (_cache[i].element === elem) { 
        return _cache[i].value; 
       } 
      } 

      return false; 
     } 

     function load(texture) { 
      var match = _cacheSearch(texture); 

      if (match) { 
       return match; 
      } 

      var val = _loader.load(texture); 
      _cachePush(texture, val); 

      return val; 
     } 

     return { 
      load: load 
     } 
    }; 

    function getInstance() { 
     return (_instance) ? _instance : _instance = Loader(); 
    } 

    return { 
     getInstance: getInstance 
    } 
})(); 

Чтобы использовать и кэшировать текстуру, которую нужно вызвать:

TextureLoader.getInstance().load(texture); 
Смежные вопросы