Jump to content

How to improve the performance for a huge model


fdeng
 Share

Recommended Posts

Hi Everyone,

I want to render a very very big model in my project using BJS, but the performance is very poor(the fps is about 5), that is  intolerable.

Some info about my model:

number of indices: 14349177

number of vertices: 7450965

number of meshs: 12043

As only color with RGBA is used for the meshs, I build a material map(148 materials included in the  map) 

for(...){
var matId = br.readInt32();
var R = br.readFloat32();
var G = br.readFloat32();
var B = br.readFloat32();
var A = br.readFloat32();
var stdmat = new BABYLON.StandardMaterial(matId, scene);
stdmat.diffuseColor = new BABYLON.Color3(R, G, B);
stdmat.alpha = A;
materialMap.push({ id: matId, material: stdmat});
}

Mesh link the material in the map:

var matItem = materialMap.getMaterial(object.matId);
if (matItem === null)
matItem = defaultMaterial;
babylonMesh.material = matItem.material;

Screen capture with instrumentation:

image.thumb.png.926b4d4b0b4d92ccbcdc73d3a8afb853.png

Any advice to improve the performance of such a huge model?

And,  the draw calls is 13296, that is much more than the number of the materails I created. Which factors decide the draw calls, how can reduce it?

Link to comment
Share on other sites

I think each mesh requires as many draw calls as it has subMaterials, which would explain the huge draw calls count.

Any hint about what you are trying to render ? A full city ? A very detailed building ?

The easiest way to improve performances would be

-> Freeze meshes not moving. If a mesh only move "sometime" (on user input for example), keep it frozen when it's not. There's some true optimization here, if not done already.

-> Merge meshes sharing materials together, you will reduce the draw calls count, also some true optimization.

It's harder, but you will also need some LOD and / or baking into texture, because I'd say your triangle count is way too high...

Everything's here : https://doc.babylonjs.com/how_to/optimizing_your_scene

Good luck !

Link to comment
Share on other sites

@SvenFrankson, thanks for the advice.

What I am trying is a very detailed building information model(BIM),  a whole subway station with all kinds of building elements, structures,  equipment,  pipelines, and so on.

There are more than 10k entities in this model, each entity has its own information, and must be pickable.

As each entity is parsed to a mesh, so there are so many meshes need to draw.

Besides merging the meshes, I have an thought but not sure if it is possible , and  how to implement it.

That is , can Babylon support to just draw the meshes in sight of the active camera?  When camera moving or rotating, the meshes in the camera's view change as well, at every moment, only feed the meshes can be seen to draw.

Link to comment
Share on other sites

@fdeng

Also, try and make use of the scene optimizer - the docs are below:

https://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer

 

Also perhaps use octrees if this applies to your scene.

 

And if you need to check for occlusion, take a look at the PG scene below:

http://www.babylonjs-playground.com/#2ACATZ

Take a look at your console, as I'm writing a message when the smaller mesh is occluded. Not my original scene, but modified for easier camera control. With this info, you can either dispose of hidden meshes or set their visibility to 0.

DB

 

Link to comment
Share on other sites

If it's only one station you wan't to display, I'd say your problem could come from the fact your meshes are not designed to be used in a real time application. Where did you got them ?

Every 3D drawing software has a decimator tool to reduce the amount of triangles in a model, try using it on pieces too detailed.

 

The fact you want to keep the ability to pick meshes make it harder to reduce the mesh count.

I'd try something like this : https://www.babylonjs-playground.com/ts.html#IDBWZN#1

The rail sleepers are merged together, so only 1 draw call, but when picking you can get the index using the world position.

 

A more generic and elaborated way could be using another information in the mesh, for example the UV2 channel if you are not using it yet.

https://www.babylonjs-playground.com/ts.html#IDBWZN#2

Here, you merge the meshes but stores an information about their original index in the UV2 channel. Whenever you click, check the value of the UV2 channel where you clicked, and you know which element you picked in the mesh.

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...