Optimizing model with very high poly count. GLTF export

Hello everyone,

I created this model in 3D`s Max and exported it in gltf format, using babylon scene exporter.

All the furniture in the scene is imported, and is not optimized for web. The total polycount is around 1.000.000 polys with furniture, and without furniture is around 8.000 :grinning:. As expected, when i upload it into babylon.js sandbox it takes a while to load and the FPS won`t go higher than 40.

My question is if there is a way to improve the loading time and FPS using the same models, without having to make them low poly?

Thank you all… :blush:

Hi @Ugene and welcome to the forum!

Maybe something can be done using instancing. Loading would be faster. Not sure for rendering performance.
ping @Drigax

1 Like

Thank you for the quick response @Cedric.

I will instance the models and see what happens. My main focus is on faster loading rather than rendering performance, so if instancing will improve this, it will be good enough for what i need right now.


1 Like

I agree with @Cedric, instancing your reused geometry such as your wall segments and furniture should reduce your file size and loadtime significantly. There only looks to be about a dozen or so unique meshes in your scene. I’m not sure the format of the geometry as you imported it, but if the whole scene was flattened to a single mesh, that may help explain the long loading time.

In addition we provide a simple mesh optimizer that removes duplicate verts via the babylon object properties that you can enable for your meshes in scene:

I also recommend using Draco compression, which is a more intelligent compression algorithm for geometry. The Max2Babylon exporter can perform this compression during export, however this requires installation of the gltf-pipeline toolkit from the npm repository. You can read more on this here: 3DSMax to glTF - Babylon.js Documentation

1 Like

also pinging @PatrickRyan to see if he has any other suggestions for optimizing this scene’s load time.

@Ugene, I think that @Cedric and @Drigax covered the most important parts of how to reduce your file load. For the instancing of the meshes, all of the chairs for example, I would add point helpers to your scene to represent the position and rotation of all chairs in your scene and export the scene with the point helpers instead of chairs. Export one chair at an identity rotation with the pivot point matching where you placed the point helper. For example, maybe you place the point helper at the floor, right in the center of the horizontal bounds of the chair. Then you would set the chair pivot to the same place. It’s important that the point helper is rotated and positioned as you want the chair to be positioned because you will use this position and rotation for the instance.

You can do this with every element in your scene that has a duplicate somewhere. This will mean that you are only loading one chair in isolation from the entire scene as the point helpers are simply a transform and won’t take up a lot of disk space for loading. Then you scrub the scene looking for the chair point helpers (which will be node transforms in Babylon) and create an instance for each one setting position and rotation to match.

The other thing to watch is the size of textures as these can cause a big hit to load, but it appears that you are either assigning factors for your material colors or have very simple textures that are likely small to begin with.

This approach takes a bit more planning on the asset creation side, but you will find that the extra time up front will help in your scene being faster to load and with instancing it will save a lot of draw calls which will speed up your frame rate. Let me know if you have more questions.

1 Like

I thank you all for the useful information. It really helped me to quickly solve this isssue.

Instancing worked very well in this case. I managed to instance most of the furniture meshes and it had a significant impact on loadtime. I only used the vert optimizer from babylon obj properties, but i plan to use Draco Compression to see how much the performance will improve.

@PatrickRyan using point helpers sounds like a very good alternative to this issue. I never thought about it since i use them very rarely, but i will try this solution for sure. I agree with the fact that it will require a bit more planning on my part, but if the end result will increase performance then it`s worth it. Also i like the idea of having more alternatives.

@Drigax you said that if the whole scene was flattened to a single mesh, it may explain the long loading time. Can you please explain if it`s ok in this case to have one mesh or multiple? For example should i attach a group of chairs and a table in one mesh, or should i make them separate?

Thank you everyone.

1 Like


Say you have a table with 6 chairs, where the chairs are all identical. Lets spitball and say the table is 100 triangles, while the chairs are 400 triangles or so.

If these are all flattened to a single mesh, then we have 100+400*6 = 2500 triangles to load and render.

If the chairs were instanced and reused then instead you only have 100 + 400 = 500 triangles to load, and we can render the instances efficiently in our engine as well, so we should see some speedup in the rendering performance as well.

As a general rule of thumb, you want to reuse and reduce geometry as much as possible!

In addition to the instancing, which only reduces draw calls btw, doesn’t 3ds Max have ways to dissolve vertices, faces, or edges? If not, I would ditch it for Blender 2.80.

If you actually made this stuff, then your left hand (your modeling) is just twisting your right (your BJS scene) behind your back. Clearly getting all the vertices out of the meshes in the modeling phase is FAR superior. If you just do not know how to do that, the investment is probably worth it.

Sorry, for being maybe too frank, but in a multiple step process, you are trying to fix the wrong one.

Thank you for the explanation @Drigax :grinning:

Hi @JCPalmer, in my scene all the furniture meshes are downloaded from TurboSquid.

When i do the modeling i try to dissolve as much useless geometry as possible, but in this case i wanted to use the downloaded ones to save some time. In the future i will model all the existing assets, but for now i decided to stick with them because this scene is just for brief showcasing.

Thank you the reply.

Glad you can if you wanted to. I see a number of people without that ability trying to put through stuff they did not make. Especially those using Blender, since it is free. In truth, they just installed Blender & are hanging on for dear life.

I have found though, that you almost never need to make your own stuff, other than rooms & larger stuff. There are absolutely great specimens in abundance. They are made by people who consider it “done” a little early for real time situations, but getting them ready is a lot easier than what it took to get them as far as they got.

Some are really old, but those ones can really clean up far better than expected, when you change to a material friendly to PBR.

These modelers, I think, are using extra vertices sometimes just for aids in modeling, & also do not care how many vertices it takes. Maybe they see it as a badge of pride to have massive #'s of verts. They even make things which are completely inside something else, & cannot even be seen. They may also see themselves as documentors, or something.

The skills to do a little touch up, reduce vertices, & swap out for PBR materials are probably even more important than knowing ALL the things you need to know to make something that does not look like crap.

ask exporter author to support MSFT_lod

@ycw, can you explain why MSFT_lod would be useful in this instance?

Load the least lod mesh first

"extensions": {
    "MSFT_lod": {
         "ids": [ 1, 2, ... n]
                            ^---load this on init

then, async load more-detail meshes based on screen coverage value.

 "extras": {
      "MSFT_screencoverage": [ 0.5, 0.25, 0.125, ... ]

suppose coverage is 0.3, then async load corresponding lod1 mesh.

it solved both loading time and fps. :thinking:

I can see how having multiple LOD versions of the mesh may help load times, but this asset doesn’t seem overly complex, we may want to prioritize some simple fixes on the creation side before we try to optimize with multiple versions of the asset.

I definitely agree though, having lower poly versions of the asset to load as a placeholder would speed up loading a bit, in that theres less time till you see something, but we’re right back where we are if it then takes forever to load in the full poly version.

yes, the suggestion of mine is about loading stragtery… rather than model massaging.