Three .js crash per 100 cubic animation

In my scene, I have 4 spotlights 3 of which are attached to the camera and about 100-300 cubes. I have many categories of cubes, each of which ranges from 100 to 300. Only one category of cubes can appear on my scene at any time based on the choice of the user menu.

(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 cubes for each category, for example:

 var materials = [ backgroundMaterial, backgroundMaterial, backgroundMaterial, backgroundMaterial, productMaterial, backgroundMaterial ]; var cubeMaterial = new THREE.MeshFaceMaterial( materials ); var object3D = new THREE.Mesh( geometryBox, cubeMaterial ); 

The backgroundMaterial determined from 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 productMaterial every time inside the loop, as the texture is different for each 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 grids to the scene at this moment, and they are set to visible = false

after that I click cubes on an array object, each array inside this object is a category of cubes from 100 to 300 in length.

When my application launches, I run an animation like the one below that brings the category of cubes to 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 ) 

In addition, you will notice another function call inside the spiral: this.models.reset( category );

Which code is lower and essentially rewrites the position of the objects and sets them to visible = false and finally removes 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 ) 

Everything works smoothly in the PC, and I run from 36 frames per second. My gpu is the new nvidia GTX (I don't know if 36 is acceptable, though).

The problem is that when I try to run my application on my nexus 5 with the latest chrome, I get a huge fps loss between the transition of cubes that go out of stage and other cubes. Most times, this leads to chrome crash ... In addition, if I do not change the category and the animation does not play, it works fine on my mobile device.

PS: I canโ€™t combine geometries, since each grid must move through each user when choosing a user. (If I'm not mistaken at least)

What could be causing this performance / crash, and how do you approach a similar scenario in which you move 200 cubes per scene and another 200 inside the scene? Are there any tips that I should take into account, bearing in mind that I'm still new to three.js.

Any other source that may be causing is required, please let me know and I will update my question.

+6
source share
1 answer

First of all, 36 fps is acceptable. As a rule, I use 25 frames per second as the minimum minimum.

now for the problem. nexus 5 has a much slower gpu than your pc. since shaders are passed directly to gpu, speed matters. this is the same problem when you try to play crysis on a budget computer, gpu is just not powerful enough to process all the data fast enough.

MAY be the solution to add all cube geometries to a single grid, possibly using THREE.MeshFaceMaterial to apply different materials to each cube. one mesh with 100 geometry is processed faster than 100 meshes with 1 geometry. but as I said. it also may be, it does not solve anyting at all, it is more from the city of Mary.

EDIT: Adding geometry to a single grid and determining which geometry was clicked.

I thought about this a little more, and click geometry can be detected. it is not very, but it can give you some ideas on how to do this. just add another property to the faces of the geometry.

 var addGeometry = function(baseGeometry, addedGeometry){ for(i in addedGeometry.faces){ addedGeometry.faces[i].parent = addedGeometry; } baseGeometry.add(addedGeometry); } 

then, when raycasting, you do not name the object property, but the face.parent property, it should contain click geometry that you can manipulate as you like.

but then again, I donโ€™t know how this will work. However, it is worth a try.

something else you could try is to use webworkers .

+2
source

Source: https://habr.com/ru/post/980077/


All Articles