Jump to content

Babylon.js very slow


Kesshi
 Share

Recommended Posts

Hi,

currently i try to decide if i use Babylon.js or Three.js for my next big project.
I would like to use babylon because it has some nice features and it is written in TypeScript.
The problem is that babylon.js seems to be much slower compared to three.js.

I made a test with a big obj file (about 6 mb + 6 textures) containing several meshes.
After loading the file i created 64 clones.

Here are the results (tested in chrome 64 bit):

Three.js (r71):
obj loading = 10.6 seconds
creating the clones = 0.5 seconds
rendering performance = 11 FPS

Babylon.js (v2.2):
obj loading = 44.5 seconds
creating the clones = 45.6 seconds
rendering performance = 0 FPS (< 0.5 FPS)

As you can see babylon.js is much much slower.
I think i could solve the issue with the slow obj loading if i just use the obj loader from three.js and modify it for babylon.

But what about the slow Mesh.clone() operation and the FPS?
Why is cloning that slow?

Here is part of my code. Is something wrong?

BABYLON.SceneLoader.ImportMesh(null, "/content/", "furniture.obj", scene, function (meshes) {    for (var i = 0; i < meshes.length; ++i) {        meshes[i].rotation.x = -Math.PI * 0.5;    }    createScene();});function createScene(pMeshes) {    var tNow = (new Date()).getTime();    var tMax: number = 8;    var x: number;    var y: number;    for (x = 0; x < tMax; ++x) {        for (y = 0; y < tMax; ++y) {            for (var i = 0; i < pMeshes.length; ++i) {                var tMesh: BABYLON.Mesh = pMeshes[i];                var tIndex = x * tMax + y;                var tClone;                if (tIndex > 0)                    tClone = tMesh.clone("mesh_clone_" + tIndex);                else                    tClone = tMesh;                tClone.position.x = -tMax * 0.5 + (x * 3);                tClone.position.z = -tMax * 0.5 + (y * 2);            }        }    }}
Link to comment
Share on other sites

Would be great to know how complex the object is.

 

The OBJ Loader is rather new to all of us, I guess there are improvements to be made :-)

 

I also believe that ThreeJS's clone is actually the Instance method of Babylon - The geometry is being reused and not duplicated. Try using instances - http://doc.babylonjs.com/tutorials/How_to_use_Instances and see if it helps you. 

That's also the reason for the lower performance - the mesh's geometry was duplicated many times (8, to be exact).

 

A small thing about your code - 

createScene();

The function requires the meshes array (pMeshes). Is it really working the way you wrote?

Link to comment
Share on other sites

Here is the link to the obj:

https://drive.google.com/file/d/0B1FKnpnB3KKIei04WTNDUWp6Ukk/view?usp=sharing

 

I just tried the instances.

I replaced the line:

tClone = tMesh.clone("mesh_clone_" + tIndex);

with this line:

tClone = tMesh.createInstance("mesh_clone_" + tIndex);

 

The FPS increases to 19 FPS but the time to create the instances is the same (still over 40 seconds  :(  )

And i think i can't use instance because it looks like all instances share the same parent. Later in the project this is not possible or

very complicated.
How can i create a clone/instance/reference of a mesh as fast as possible without duplicating the whole geometry?

 

 


A small thing about your code - 

createScene();

The function requires the meshes array (pMeshes). Is it really working the way you wrote?

 

That was just a mistake while simplifying the code in order to post it here. In my real code its correct.

Link to comment
Share on other sites

Instances are your friends in that case - they share the same geometry (I am not sure what you mean by parent), but their world matrix can be different.

 

I find the 40 seconds to be way to much (Haven't looked at the object yet). I wonder what the cause is. I'll try finding the time to look into that. At least the FPS was increased! :-)

What version of Babylon are you using? 

Link to comment
Share on other sites

I use version 2.2

I just profiled it a bit in chrome. One of the problems with the slow clone() and createInstance() seems to be a call to BABYLON.Tools.ExtractMinAndMax(). It is called from refreshBoundingInfo(). It seems that the BoundingBox is recalculated for every clone/instance. Why? It should be ok to just copy the boundingbox info in this case.

 

Regarding the use of Instances. The problem is that they only have a world matrix. My Objects have a hierarchy/graph with local transformations. It would be very complicated to keep the world matrix of the instances in sync with the local matrix inside the hierarchy. Thats why i said i need to give every clone/instance a different parent.

Link to comment
Share on other sites

You are right, this should be calculated only once. Let's see how this can be done a bit better. The bounding box must be calculated for each mesh after it was created, this is why this function is being called. But maybe it can be optimized.

 

About the parents problem - create a parent right after loading all of the meshes.  This way they all keep their local transformations, and you can transform the parent object. Clone or create an sinatnce of this parent, and the rest will be done automatically for you. Theoretically :-) If this doesn't work, let us know.

 

I would also reduce the amount of vertices all of your objects have (just a recommendation). The debug layer states there are ca. 6 million active vertices. Maybe run simplification before loading the object?

 

And just a small correction for something I said earlier - the geometry is being reused in clones as well. The other properties are being copied (and not shared between meshes). In your case it would be wise to use instance.

Link to comment
Share on other sites

One more issue. The memory consumption (memory usage of chrome process).

Same test as described above.

Three.js: 410 MB  

Babylon (instances): 990 MB

Babylon (clone): 1230 MB

 

After all these tests i decided to use Three.js for my project. It seems to have less problems with complex objects.

Maybe i can use BabylonJs for some other project in the future but at the moment it doesn't seem to be ready for my use case.

Link to comment
Share on other sites

Hi 

 

We are not insulted :-)  (I do hope so at least). Each Framework has its ups an downs, we do try to fix bugs and make things better (without trying to constantly compare to Three.js, which is a wonderful framework).

The higher memory consuption is probably due to the way Babylon stores the vertices, materials etc'. Can be a bit redundant, but is quicker to render. Again, ups and downs for each way.

 

If there is anything we can help with, please let us know. I will anyhow try and find optimization possibilities for the entire process, as 40 Seconds is truly way too much to load and clone the object.

Link to comment
Share on other sites

That's a really interesting topic.I'm sad babylon.js was not able to address your use case but I'll make it personal to fix any perf issues we may have with cloning

 

@Temechon: do you mind checking why obj importer is slower than expected?

 

@Raanan: are you checking the clone and memory usage issues? I can do it else. Please let me know :)

Link to comment
Share on other sites

Ok so I fixed a performance issue with clone and createInstance 

 

Using your .obj I can go through all the cloning process in 0.7s on my computer (X1 Carbon) down from 24s :)

 

We are also working on improving the .obj loader

 

On the clone front: I wanted to mention that clone is a COMPLETE clone, meaning that we go through all properties to effectively clone them one by one

Link to comment
Share on other sites

@Dektakosh: That was a very fast fix.

I will try babylon again tomorrow, when i'm at work. Maybe i will change my mind :-)

 

Regarding the obj loading. Some days ago i was looking at the obj loader code a bit. If i remember correctly, one reason for the long load times seems to be this function:

https://github.com/BabylonJS/Babylon.js/blob/master/loaders/OBJ/babylon.objFileLoader.ts#L278

It is called for each loaded vertex which results in an O(n^2) issue. 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...