#javascript #three.js
#javascript #three.js
Вопрос:
ТРИ.TextureLoader() ведет себя неожиданным и ошибочным образом. Функция load() класса пытается / загружает одни и те же ресурсы несколько раз (т.Е. 20 или более раз).
Ниже на рисунке показано это поведение с использованием консоли браузера:
Далее следует код, используемый для загрузки и использования текстур:
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
Что сделано неправильно? Почему одно и то же изображение загружается несколько раз?
Ответ №1:
Дело в том, что THREE.TextureLoader()
по умолчанию текстуры не кэшируются, но я думаю, что это необходимо, или, по крайней мере, попросить вас не делать этого. Это означает, что если у вас есть 400 объектов с одинаковой текстурой, библиотека сделает 400 HTTP-запросов для одних и тех же ресурсов.
Ниже приведено простое решение (одноэлементный шаблон / шаблон модуля) модуль кэша:
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);