Three.js: THREE.TextureLoader() memuat tekstur yang sama beberapa kali (yaitu 20 kali atau lebih)

Dibuat pada 5 Okt 2016  ·  3Komentar  ·  Sumber: mrdoob/three.js

Deskripsi masalah

THREE.TextureLoader() berperilaku dengan cara yang tidak terduga dan salah. Fungsi load() dari kelas mencoba/memuat aset yang sama beberapa kali (yaitu 20 kali atau lebih).

Di bawah pada gambar diilustrasikan perilaku ini menggunakan konsol browser:
bdhg9

Kode yang digunakan untuk memuat dan menggunakan tekstur berikut ini:

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

Untuk keperluan debugging, Anda juga dapat menemukan pratinjau langsung di sini: https://alexprut.github.io/earth-defender/ dan kode permainan di sini: https://github.com/alexprut/earth-defender/tree/master/ klien/js

Versi Three.js
  • [ ] Dev
  • [ ] r81
  • [x] r80

    Peramban
  • [x] Semuanya

  • [ ] Chrome
  • [ ] Firefox
  • [ ] Internet Explorer

    OS
  • [x] Semuanya

  • [ ] Jendela
  • [ ] Linux
  • [ ] Android
  • [ ] iOS
    Persyaratan Perangkat Keras (kartu grafis, Perangkat VR, ...)
Help (please use the forum)

Komentar yang paling membantu

XHRLoader yang dipanggil dari TextureLoader melalui ImageLoader menggunakan objek global Cache
tetapi default Cache.enabled adalah false .

Jika Anda menyetel THREE.Cache.enabled = true; tepat setelah memuat three.js
itu akan berhasil.

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

Semua 3 komentar

Saya percaya loader bekerja dengan cara yang diinginkan. Ini memuat tekstur meteor 200 kali karena Anda memintanya. Pemuat dapat dimodifikasi untuk secara otomatis menyimpan dan mengembalikan aset yang Anda minta untuk dimuat beberapa kali, tetapi ini mungkin tidak diinginkan dalam semua kasus. Browser akan mengelola cache sehingga jika semua header pada file gambar sudah benar, browser akan mengembalikan versi cache gambar setiap kali.

Dalam kode Anda:

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

Saya akan mempertimbangkan untuk menambahkan sesuatu seperti berikut:

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

Jadi, Anda mengelola cache materi yang dimuat dari array daripada dibuat ulang setiap saat. Ini akan bekerja dengan baik jika semua asteroid memiliki bahan yang sama, atau gunakan metode .clone() jika Anda ingin bahannya berbeda.

Lihat apakah itu membantu.

@calrk terima kasih itu memecahkan masalah.

Saya masih percaya THREE.TextureLoader() berperilaku dengan cara yang tidak terduga, itu akan menanyakan apakah Anda ingin men-cache atau tidak teksturnya, misalnya:

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

Saya pikir secara default loader harus men-cache tekstur untuk alasan kinerja (jika saya salah, beri tahu saya alasannya).


Di bawah ini adalah modul cache solusi sederhana (Pola tunggal / Pola modul):

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

Untuk menggunakan dan men-cache tekstur yang Anda butuhkan untuk memanggil:

TextureLoader.getInstance().load(texture);

XHRLoader yang dipanggil dari TextureLoader melalui ImageLoader menggunakan objek global Cache
tetapi default Cache.enabled adalah false .

Jika Anda menyetel THREE.Cache.enabled = true; tepat setelah memuat three.js
itu akan berhasil.

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

Apakah halaman ini membantu?
0 / 5 - 0 peringkat