Three.js: THREE.TextureLoader () загружает одну и ту же текстуру несколько раз (т.е. 20 раз или больше)

Созданный на 5 окт. 2016  ·  3Комментарии  ·  Источник: mrdoob/three.js

Описание проблемы

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

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

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

var Element = function (texture) {
    this.texture = texture;
};
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/ клиент / js

Версия Three.js
  • [] Dev
  • [] r81
  • [x] r80

    Браузер
  • [x] Все они

  • [] Chrome
  • [ ] Fire Fox
  • [] Internet Explorer

    Операционные системы
  • [x] Все они

  • [] Windows
  • [] Linux
  • [] Android
  • [] IOS
    Требования к оборудованию (видеокарта, устройство VR, ...)
Help (please use the forum)

Самый полезный комментарий

XHRLoader который вызывается из TextureLoader через ImageLoader использует глобальный объект Cache
но по умолчанию Cache.enabled - это false .

Если вы установите THREE.Cache.enabled = true; сразу после загрузки three.js
это сработает.

https://github.com/mrdoob/three.js/blob/2f469f327a10c7780c9bc69f876f9ed5049587f2/src/loaders/XHRLoader.js#L22

https://github.com/mrdoob/three.js/blob/f65e669af99feb518e31756d793a9688a2578fbd/src/loaders/Cache.js#L9

6834

Все 3 Комментарий

Я считаю, что загрузчик работает по назначению. Он загружает текстуры метеора 200 раз, потому что вы об этом просите. Загрузчик можно изменить для автоматического кэширования и возврата ресурсов, которые вы просите загрузить несколько раз, но это может потребоваться не во всех случаях. Браузер будет управлять кешем, поэтому, если все заголовки в файле изображения верны, браузер каждый раз будет возвращать кешированные версии изображения.

В вашем коде:

this.maxMeteorietes = config.maxMeteorietes || 200;

Game.prototype.createMeteorites = function (numMeteorites) {
    var meteorites = new THREE.Object3D();
    for (var i = 0; i < numMeteorites; i++) {
        var meteorite = new Meteorite().create(
            this.createUniforms(),
            this.createVertexShader(),
            this.createFragmentShader()
        );

    ....

}

Meteorite.prototype.create = function (uniforms, vertexShader, fragmentShader) {
    return new THREE.Mesh(
        new THREE.SphereGeometry(5, 5, 5),
//This line is called 200 times, and as such your loader.load() function will be called 200 times.
        this.createShaderMaterial(uniforms, vertexShader, fragmentShader)
    );
};

Я бы подумал добавить что-то вроде следующего:

var cache = [];
var loader = new THREE.TextureLoader();  //don't need a local version of this object

Element.prototype.createShaderMaterial = function (uniforms, vertexShader, fragmentShader) {
    if(cache[this.texture]){
        return cache[this.texture]; //cache[this.texture].clone();
    }
    uniforms.texture.value = loader.load(this.texture);

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

    cache[this.texture] = shader;

    return shader;
};

Таким образом, вы управляете кешем материалов, которые загружаются из массива, а не регенерируются каждый раз. Это будет хорошо работать, если все астероиды имеют одинаковый материал, или используйте метод .clone (), если вы хотите, чтобы материалы были разными.

Посмотрим, поможет ли это.

@calrk спасибо, это решает проблему.

Я все еще считаю, что THREE.TextureLoader() ведет себя неожиданным образом, он должен спросить вас, хотите ли вы кэшировать текстуры, например:

var loader = THREE.TextureLoader();
loader(texture, cache = false);

Я думаю, что по умолчанию загрузчик должен кэшировать текстуры из соображений производительности (если я ошибаюсь, дайте мне знать, почему).


Ниже приведено простое решение (шаблон синглтона / шаблон модуля) кеш-модуля:

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);

XHRLoader который вызывается из TextureLoader через ImageLoader использует глобальный объект Cache
но по умолчанию Cache.enabled - это false .

Если вы установите THREE.Cache.enabled = true; сразу после загрузки three.js
это сработает.

https://github.com/mrdoob/three.js/blob/2f469f327a10c7780c9bc69f876f9ed5049587f2/src/loaders/XHRLoader.js#L22

https://github.com/mrdoob/three.js/blob/f65e669af99feb518e31756d793a9688a2578fbd/src/loaders/Cache.js#L9

6834

Была ли эта страница полезной?
0 / 5 - 0 рейтинги