Three.js: THREE.TextureLoader () carrega a mesma textura várias vezes (ou seja, 20 vezes ou mais)

Criado em 5 out. 2016  ·  3Comentários  ·  Fonte: mrdoob/three.js

Descrição do problema

O THREE.TextureLoader () se comporta de maneira inesperada e errônea. A função load () da classe tenta / carrega os mesmos ativos várias vezes (ou seja, 20 vezes ou mais).

Abaixo na figura está ilustrado esse comportamento usando o console do navegador:
bdhg9

O código usado para carregar e usar texturas segue a seguir:

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

Para fins de depuração, você também pode encontrar uma prévia ao vivo aqui: https://alexprut.github.io/earth-defender/ e o código do jogo aqui: https://github.com/alexprut/earth-defender/tree/master/ cliente / js

Versão Three.js
  • [] Dev
  • [] r81
  • [x] r80

    Navegador
  • [x] Todos eles

  • [ ] Cromada
  • [ ] Raposa de fogo
  • [] Internet Explorer

    SO
  • [x] Todos eles

  • [ ] Janelas
  • [] Linux
  • [] Android
  • [] IOS
    Requisitos de hardware (placa gráfica, dispositivo VR, ...)
Help (please use the forum)

Comentários muito úteis

XHRLoader que é chamado de TextureLoader via ImageLoader usa o objeto global Cache
mas o padrão Cache.enabled é false .

Se você definir THREE.Cache.enabled = true; logo após carregar three.js
iria funcionar.

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

Todos 3 comentários

Acredito que o carregador esteja funcionando da maneira pretendida. Está carregando as texturas de meteoro 200 vezes porque você está pedindo. O carregador pode ser modificado para armazenar automaticamente em cache e retornar ativos que você pede para carregar várias vezes, mas isso pode não ser desejado em todos os casos. O navegador gerenciará o cache, portanto, se todos os cabeçalhos do arquivo de imagem estiverem corretos, o navegador sempre retornará versões em cache da imagem.

Em seu código:

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

Eu consideraria adicionar algo como o seguinte:

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

Assim, você gerencia um cache de materiais que são carregados de uma matriz em vez de regenerados todas as vezes. Isso funcionará bem se todos os asteróides tiverem o mesmo material ou use o método .clone () se quiser que os materiais sejam diferentes.

Veja se isso ajuda.

@calrk obrigado resolve o problema.

Ainda acredito que THREE.TextureLoader() se comporta de forma inesperada, ele deve perguntar se você deseja armazenar em cache ou não as texturas, por exemplo:

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

Acho que por padrão o carregador deve armazenar em cache as texturas por motivos de desempenho (se eu estiver errado, me diga o porquê).


Abaixo está uma solução simples (padrão Singleton / padrão Módulo) módulo de cache:

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

Para usar e armazenar em cache a textura, você precisa chamar:

TextureLoader.getInstance().load(texture);

XHRLoader que é chamado de TextureLoader via ImageLoader usa o objeto global Cache
mas o padrão Cache.enabled é false .

Se você definir THREE.Cache.enabled = true; logo após carregar three.js
iria funcionar.

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

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

akshaysrin picture akshaysrin  ·  3Comentários

Bandit picture Bandit  ·  3Comentários

seep picture seep  ·  3Comentários

konijn picture konijn  ·  3Comentários

ghost picture ghost  ·  3Comentários