in my scene I have 4 point-lights 3 of those attached on the camera and about 100 to 300 cubes. I have many categories of cubes, each between 100 - 300. Only 1 category of cubes may appear in my scene at any time based on user menu selection.
(category with 100 cubes) renderer.info:
memory:
Objectgeometries: 2
programs: 3
textures: 100
render:
calls: 203
faces: 1360
points: 0
vertices: 4080
In a loop I generate my cubes for each category like this:
var materials = [
backgroundMaterial,
backgroundMaterial,
backgroundMaterial,
backgroundMaterial,
productMaterial,
backgroundMaterial
];
var cubeMaterial = new THREE.MeshFaceMaterial( materials );
var object3D = new THREE.Mesh( geometryBox, cubeMaterial );
The material backgroundMaterial is defined out of the loop once;
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
});
and the productMaterial each time inside the loop since the texture is different for every cube.
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
});
Also I do not add the meshes into the scene at this point, and they are set to visible = false
after that I push my cubes into an object of arrays, each array inside that object is a category of cubes with length between 100 - 300.
When my application starts I run an animation like the one bellow which brings a category of cubes into the scene.
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 )
Furthermore you will notice another function call inside helix, this one: this.models.reset( category );
Which is the code below and is essentially reseting the objects position and sets them to visible = false and finally removing them from the scene.
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 a pc everything works smooth and I'm running with 36 fps. My gpu is a new nvidia GTX (I don't know if 36 is acceptable though).
The issue is that when I try to run my application on my nexus 5 with latest chrome I get a huge fps loss between the transition of cubes going outside the scene and the other cubes coming in. Most of the times this results in a chrome crash... Other than that if I don't change category and no animations are being played it works OK in my mobile.
PS: I cannot merge the geometries since each mesh has to move on each own upon user selection.(If I'm not mistaken atleast)
What could be the reason for this performance drop/crash, and how would you approach a similar scenario where you move 200 cubes outside the scene and another 200 inside the scene? Are there any tips I should take under consideration, keeping in mind that I'm still new to three.js.
Any other source required that might be the reason please let me know and I will update my question.