يتصرف THREE.TextureLoader () بطريقة خاطئة وغير متوقعة. تقوم وظيفة load () الخاصة بالفئة بمحاولة / تحميل نفس الأصول عدة مرات (أي 20 مرة أو أكثر).
يوضح الشكل أدناه هذا السلوك باستخدام وحدة تحكم المتصفح:
الكود المستخدم لتحميل واستخدام القوام فيما يلي:
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/ العميل / شبيبة
[x] r80
[x] كل منهم
[ ] متصفح الانترنت
[x] كل منهم
أعتقد أن اللودر يعمل بالطريقة المقصودة. يتم تحميل قوام النيزك 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
ستعمل.
التعليق الأكثر فائدة
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