Three.js: يقوم THREE.TextureLoader () بتحميل نفس النسيج عدة مرات (أي 20 مرة أو أكثر)

تم إنشاؤها على ٥ أكتوبر ٢٠١٦  ·  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/ العميل / شبيبة

إصدار Three.js
  • [] ديف
  • [] r81
  • [x] r80

    المستعرض
  • [x] كل منهم

  • [ ] كروم
  • [ ] ثعلب النار
  • [ ] متصفح الانترنت

    نظام التشغيل
  • [x] كل منهم

  • [ ] شبابيك
  • [] لينكس
  • [ ] ذكري المظهر
  • [] 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 () إذا كنت تريد أن تكون المواد مختلفة.

انظر إذا كان هذا يساعد.

@ كالرك بفضل أنه يحل المشكلة.

ما زلت أعتقد أن THREE.TextureLoader() يتصرف بطريقة غير متوقعة ، يجب أن يسألك عما إذا كنت تريد تخزين الأنسجة مؤقتًا أم لا ، على سبيل المثال:

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

أعتقد أنه يجب على المُحمل افتراضيًا تخزين الأنسجة مؤقتًا لأسباب تتعلق بالأداء (إذا كنت مخطئًا ، فيرجى إخبارنا بالسبب).


يوجد أدناه حل بسيط لوحدة ذاكرة التخزين المؤقت (نمط Singleton / نمط الوحدة):

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 التقييمات