Three.js: TRES.TextureLoader () carga la misma textura varias veces (es decir, 20 veces o más)

Creado en 5 oct. 2016  ·  3Comentarios  ·  Fuente: mrdoob/three.js

Descripción del problema

THREE.TextureLoader () se comporta de forma inesperada y errónea. La función load () de la clase intenta / carga los mismos activos varias veces (es decir, 20 veces o más).

A continuación, en la figura, se ilustra este comportamiento utilizando la consola del navegador:
bdhg9

El código utilizado para cargar y usar texturas es el siguiente:

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 fines de depuración, también puede encontrar una vista previa en vivo aquí: https://alexprut.github.io/earth-defender/ y el código del juego aquí: https://github.com/alexprut/earth-defender/tree/master/ cliente / js

Versión de Three.js
  • [] Desarrollo
  • [] r81
  • [x] r80

    Navegador
  • [x] Todos ellos

  • [ ] Cromo
  • [] Firefox
  • [ ] Explorador de Internet

    SO
  • [x] Todos ellos

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

Comentario más útil

XHRLoader que se llama desde TextureLoader través de ImageLoader usa el objeto global Cache
pero el valor predeterminado Cache.enabled es false .

Si configura THREE.Cache.enabled = true; justo después de cargar three.js
funcionaría.

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 comentarios

Creo que el cargador está funcionando de la forma prevista. Está cargando las texturas del meteorito 200 veces porque usted se lo pide. El cargador podría modificarse para almacenar en caché y devolver automáticamente los activos que le pida que cargue varias veces, pero es posible que esto no sea necesario en todos los casos. El navegador administrará el caché, por lo que si todos los encabezados del archivo de imagen son correctos, el navegador devolverá versiones en caché de la imagen cada vez.

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

Consideraría agregar algo como lo siguiente:

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

Por lo tanto, administra un caché de materiales que se cargan desde una matriz en lugar de regenerarse cada vez. Esto funcionará bien si todos los asteroides tienen el mismo material, o use el método .clone () si desea que los materiales sean diferentes.

Vea si eso ayuda.

@calrk agradece que resuelve el problema.

Sigo creyendo que THREE.TextureLoader() comporta de una manera inesperada, debería preguntarte si quieres almacenar en caché o no las texturas, por ejemplo:

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

Creo que, de forma predeterminada, el cargador debería almacenar en caché las texturas por razones de rendimiento (si me equivoco, avíseme por qué).


A continuación se muestra un módulo de caché de solución simple (patrón Singleton / Patrón de módulo):

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 y almacenar en caché la textura, debe llamar a:

TextureLoader.getInstance().load(texture);

XHRLoader que se llama desde TextureLoader través de ImageLoader usa el objeto global Cache
pero el valor predeterminado Cache.enabled es false .

Si configura THREE.Cache.enabled = true; justo después de cargar three.js
funcionaría.

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

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

clawconduce picture clawconduce  ·  3Comentarios

jlaquinte picture jlaquinte  ·  3Comentarios

scrubs picture scrubs  ·  3Comentarios

fuzihaofzh picture fuzihaofzh  ·  3Comentarios

konijn picture konijn  ·  3Comentarios