Nella mia scena ho 4 punti luce 3 di quelli collegati sulla fotocamera e circa 100 a 300 cubi. Ho molte categorie di cubi, ognuno compreso tra 100 e 300. Solo una categoria di cubi può apparire nella mia scena in qualsiasi momento in base alla selezione del menu utente.Three.js che si blocca su animazione 100 cubi
(categoria con 100 cubetti) renderer.info:
memory:
Objectgeometries: 2
programs: 3
textures: 100
render:
calls: 203
faces: 1360
points: 0
vertices: 4080
In un ciclo genero miei cubi per ogni categoria come questo:
var materials = [
backgroundMaterial,
backgroundMaterial,
backgroundMaterial,
backgroundMaterial,
productMaterial,
backgroundMaterial
];
var cubeMaterial = new THREE.MeshFaceMaterial(materials);
var object3D = new THREE.Mesh(geometryBox, cubeMaterial);
Il materiale backgroundMaterial
è definito fuori dal giro una volta;
var backgroundMaterial = new THREE.MeshPhongMaterial({
color: this.options.models.boxColor,
specular: this.options.models.boxSpecular,
//emissive : 0xefefef,
//side: THREE.DoubleSide,
overdraw: false,
transparent: false,
metal:true,
shininess: this.options.models.boxShininess,
reflectivity: this.options.models.boxReflectivity,
fog:false
});
e il prodottoMateriale ogni volta all'interno del ciclo poiché la trama è diversa per ogni cubo.
var productMaterial = new THREE.MeshBasicMaterial({
map: productModelTexture,
color: that.options.models.boxColor,
specular: that.options.models.boxSpecular,
//emissive : 0xefefef,
side: THREE.FrontSide,
overdraw: false,
transparent: false,
metal:true,
shininess: that.options.models.textureShininess,
reflectivity: that.options.models.textureReflectivity,
opacity: 1,
fog:false
});
Inoltre non aggiungo le maglie in scena a questo punto, e sono impostati visible = false
dopo che spingono le cubetti in un oggetto di array, ogni array dentro quell'oggetto è un categoria di cubi con lunghezza compresa tra 100 e 300.
All'avvio dell'applicazione eseguo un'animazione simile a quella del muggito che introduce una categoria di cubi nella scena.
helix : function(category) {
if (this.models[category] && this.models[category].length > 0) {
TWEEN.removeAll();
new TWEEN.Tween(this.camera.position).to({x:0,y:0,z:90000}, 1000).easing(TWEEN.Easing.Exponential.InOut).start();
new TWEEN.Tween(this.camera.rotation).to({x:0,y:0,z:0}, 1000).easing(TWEEN.Easing.Exponential.InOut).start();
this.models.reset(category);
for (var i in this.models[category]) {
var model = this.models[category][i];
model.visible = true;
this.scene.add(model);
new TWEEN.Tween(model.position).to({
x: model.helix.position.x,
y: model.helix.position.y,
z: model.helix.position.z
}, randBtwn(1000, 3000)).easing(TWEEN.Easing.Exponential.InOut).delay(1001).start();
new TWEEN.Tween(model.rotation).to({
x: model.helix.rotation.x,
y: model.helix.rotation.y,
z: model.helix.rotation.z
}, randBtwn(1000, 3000)).easing(TWEEN.Easing.Exponential.InOut).delay(1001).onComplete(function(){
}).start();
}
}
}.bind(that)
Inoltre si noterà un'altra chiamata di funzione all'interno dell'elica, questo: this.models.reset(category);
Qual è il codice qui sotto ed è essenzialmente reseting la posizione degli oggetti e li mette a visible = false
e, infine, la loro rimozione dalla scena.
reset : function(category, callback) {
for (var j in this.models) {
if (this.models[j] instanceof Array && this.models[j].length > 0 && category !== j) {
for (var i in this.models[j]) {
var model = this.models[j][i];
model.visible = true;
new TWEEN.Tween(model.position).to({
x: model.outside.position.x,
y: model.outside.position.y,
z: model.outside.position.z
}, 1000).easing(TWEEN.Easing.Exponential.InOut).start();
new TWEEN.Tween(model.rotation).to({
x: model.outside.rotation.x,
y: model.outside.rotation.y,
z: model.outside.rotation.z
}, 1000).easing(TWEEN.Easing.Exponential.InOut).onComplete(function (m){
m.visible = false;
this.scene.remove(m);
if (callback) {
callback();
}
}.bind(that, model)).start();
}
}
}
}.bind(that)
In un pc funziona tutto liscio e sono in esecuzione con 36 fps. La mia gpu è una nuova nvidia GTX (non so se 36 sia accettabile).
Il problema è che quando provo a eseguire la mia applicazione sul mio nexus 5 con l'ultimo chrome, ho una perdita enorme di fps tra la transizione di cubi fuori dalla scena e gli altri cubi che entrano. Il più delle volte questo risultato in un crash di cromo ... A parte questo, se non cambio categoria e non si riproducono animazioni, funziona bene sul mio cellulare.
PS:. Non posso unire le geometrie dal momento che ogni rete deve muoversi su ogni proprio su selezione utente (se non mi sbaglio atleast)
Quale potrebbe essere la ragione di questo calo/crash prestazioni, e come ti avvicineresti ad uno scenario simile in cui muovi 200 cubetti fuori dalla scena e altri 200 all'interno della scena? Ci sono dei consigli che dovrei prendere in considerazione, tenendo presente che sono ancora nuovo su three.js.
Qualsiasi altra fonte richiesta potrebbe essere la ragione, fatemelo sapere e aggiornerò la mia domanda.
Ho pensato anche a questo, per unire le geometrie, ma il fatto è che ho bisogno di animazioni separate per ogni cubo al clic/selezione dell'utente. Quindi suppongo che se dovessi unirli non sarei in grado di animare 1 cubo se l'utente fa clic su di esso. – Syd
L'animazione non sarà un gran problema, puoi semplicemente regolare la posizione della geometria rispetto alla mesh. il clic è un'altra storia, puoi ottenere la distanza, faccia, facciaIndex, oggetto e punto, ma sfortunatamente non il bambino oggetto che è stato cliccato. Puoi controllare quale faccia appartiene a quale geometria, ma temo che ciò causerebbe solo più problemi di quanti ne risolva. –
è ancora possibile animare i vertici del cubo nella geometria unita. – makc