# Optimizing the scene for a huge amount of simple meshes

**URL:** <https://forum.babylonjs.com/t/optimizing-the-scene-for-a-huge-amount-of-simple-meshes/7398>\
**Category:** Questions\
**Created:** [December 5, 2019, 3:13pm UTC](https://forum.babylonjs.com/t/optimizing-the-scene-for-a-huge-amount-of-simple-meshes/7398 "2019-12-05T15:13:53Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mykyta\_Fedorovskiy](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/mykyta_fedorovskiy/32/3741_2.png) [@Mykyta\_Fedorovskiy](https://forum.babylonjs.com/u/Mykyta_Fedorovskiy)\
**Post date:** [December 5, 2019, 3:13pm UTC](https://forum.babylonjs.com/t/optimizing-the-scene-for-a-huge-amount-of-simple-meshes/7398/1 "2019-12-05T15:13:54Z")

</div>

Hi all,

I would like to council you regarding scene optimization.

- I tried a lot of things from here: [Optimize your scene - Babylon.js Documentation](https://doc.babylonjs.com/how_to/optimizing_your_scene). But the effect was hardly measurable or it broke my scene, meshes were not drawn anymore etc…
- I also checked out scene optimizer.

However I am looking for additional leverages.

I think my situation is somewhat specific.

- I am drawing a huge amount of simple meshes
- Imagine a warehouse with a lot of boxes in the shelves. (Shelves and boxes are instanced wherever possible).
- The shelves are all instanced (I spawn a shelve prototype and then create instances of those prototypes)
- The products in the shelves can be displayed on demand. Those are drawn as simple cubes with different colors (5-10). There might be up to 30k boxes (all instanced, such that I have only as much “non-instanced” meshes as I have colors (5-10).
- Things become very slow (fps) if I spawn the boxes. (I am a bit surprised as according to my perception the shelves are harder to render then the boxes, however it seems to be contrary)

As mentioned I am looking for additional leverages.  
Which settings would you advise me to test / which are important in your experience?  
Or more in general do you have tips for me how I can discover performance issues?

Some other ideas I wanted to test (maybe you could evaluate those before I waste time ^^):

- Create a sphere around the free cam (“horizon”) to reduce the number of meshes visible
- Displaying the boxes on an transparent offscreen canvas and sync the position of the free cam - However I am not sure how it will behave, if one scene is faster then the other.

Thank you in advance.

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [December 5, 2019, 3:48pm UTC](https://forum.babylonjs.com/t/optimizing-the-scene-for-a-huge-amount-of-simple-meshes/7398/2 "2019-12-05T15:48:42Z")

</div>

You should first look for where the time is spent by using the Performance tab (if using Chrome).

With so many meshes, it’s expected that `scene._evaluateActiveMeshes` will take some time. So, one thing you can do is helping the `_evaluateActiveMeshes` function by reducing the work it must do.

For eg, you could check that shelf X is visible (check the bouding box against the frustum - `mesh.isInFrustum()`):

- if not, call `.setEnabled(false)` on it and on all products pertaining to this shelf
- if yes, call `.setEnabled(true)` and `.alwaysSelectAsActiveMesh = true` on it and on all products pertaining to this shelf

It would even be better to reconstruct the `scene.meshes` array by putting in only meshes that you determined as being visible through the process described above.

Maybe the `isReady` functions of the materials take also some time: you can call `.freeze()` on them to help things.

But as said above, you should start by checking what really takes some time before going any further.

---

<div class="post-metadata">

**Author:** ![thomlucc](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/thomlucc/32/4046_2.png) [@thomlucc](https://forum.babylonjs.com/u/thomlucc)\
**Post date:** [December 5, 2019, 4:00pm UTC](https://forum.babylonjs.com/t/optimizing-the-scene-for-a-huge-amount-of-simple-meshes/7398/3 "2019-12-05T16:00:24Z")

</div>

Hi @Mykyta_Fedorovskiy, you could use instance buffers (you can add parameters to instances - like the color). More details on the video: [Weekly Video: Fun with Instance Buffers](https://forum.babylonjs.com/t/weekly-video-fun-with-instance-buffers/6741)

---

<div class="post-metadata">

**Author:** ![Mykyta\_Fedorovskiy](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/mykyta_fedorovskiy/32/3741_2.png) [@Mykyta\_Fedorovskiy](https://forum.babylonjs.com/u/Mykyta_Fedorovskiy)\
**Post date:** [December 6, 2019, 3:02pm UTC](https://forum.babylonjs.com/t/optimizing-the-scene-for-a-huge-amount-of-simple-meshes/7398/4 "2019-12-06T15:02:19Z")

</div>

Hey guys,

thank you very much for the advices.

@thomlucc I will definitely be able to reduce the number of non-instanced meshes even furher. So thank you here.

@Evgeni_Popov:

- you are totally right: \_evaluateActive meshes takes ~70% of the renderLoop

- I am a bit surprised that it is called several times (see Screenshot below). Is it normal or do I have a glitch somewhere?

- In general I have a quite suffisticated datastructure behind the scene. So I can tell anytime which boxes are in which shelves.

- Still I have a question:  
(1) Shell I do this directly in the render-loop or is this there a better way?  
(2) As far as I understand babylon does not render not visible meshes (i.e. behind a Wall). will I loose that or is mesh.isInFrustum() that smart?

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/f/f2eebb1257187bd5cfb1c9b4016a4589e827fea8.png)

Here is an example for one of my scenes to boost your imagination:

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/2X/5/5d8294a2d074d3698de25c9982f0b1054542fa32.png)

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [December 6, 2019, 3:27pm UTC](https://forum.babylonjs.com/t/optimizing-the-scene-for-a-huge-amount-of-simple-meshes/7398/5 "2019-12-06T15:27:12Z")

</div>

\_evalauteActiveMeshes is called every frame UNLESS you can call secene.freezeActiveMeshes()  
This will boost your perf by a order of magnitude 😉

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [December 6, 2019, 5:32pm UTC](https://forum.babylonjs.com/t/optimizing-the-scene-for-a-huge-amount-of-simple-meshes/7398/6 "2019-12-06T17:32:12Z")

</div>

As @Deltakosh said, calling `scene.freeActiveMeshes()` will help tremendously for `_evaluateActivesMeshes` as this will make this function takes virtually 0 time.

However, the problem is that the visible mesh list won’t be reconstructed according to the camera view. So, to be usable in your case, you should flag all meshes with `.alwaysSelectAsActiveMesh = true` and then call `scene.freeActiveMeshes()`. It means all meshes will be rendered, whatever the camera view is.

It’s up to you to see if it’s better to have all meshes rendered at each frame and avoid the work done by `_evaluateActivesMeshes`, or let the latter do its job as usual.

Seing your screenshot, I think you will get the best performance by grouping all meshes into a single mesh (`Mesh.mergeMeshes`) (try to have as few different materials as possible).

> [@Mykyta\_Fedorovskiy](#):
>
> The products in the shelves can be displayed on demand.

Does it mean the product must disappear from the shelf? If yes, you would need to remove the box from the geometry indices of the merged mesh.

> [@Mykyta\_Fedorovskiy](#):
>
> Shell I do this directly in the render-loop or is this there a better way?

Use for eg `scene.onBeforeRenderObservable` to update the `scene.meshes` list (if you don’t merge meshes).

> [@Mykyta\_Fedorovskiy](#):
>
> As far as I understand babylon does not render not visible meshes (i.e. behind a Wall)

Yes it does (if the object is at least partially in the frustum, meaning it is sent to the GPU for rendering). It’s the zBuffer that will make the object not visible in this case, because the wall is in front of it.

You can implement your own culling strategy to fill the `scene.meshes` list (managing “by hand” the product visibility inside a shelf is a first step), but I don’t see a lot of possibility for your scene, except may be by having bounding boxes around big structures (each shelf (+products inside), big white thing on the right in your screenshot, …) and testing the visibility of these boxes yourself: if not visible, all meshes inside the bouding box are not visible.

---

<div class="post-metadata">

**Author:** ![GabrielMarcondes](https://avatars.discourse-cdn.com/v4/letter/g/a8b319/32.png) [@GabrielMarcondes](https://forum.babylonjs.com/u/GabrielMarcondes)\
**Post date:** [December 6, 2019, 8:21pm UTC](https://forum.babylonjs.com/t/optimizing-the-scene-for-a-huge-amount-of-simple-meshes/7398/7 "2019-12-06T20:21:21Z")

</div>

Awesome work dudeeeee!!!

Nice post I going to use some of the ideas here.

Kudos to @Evgeni_Popov!!

---

<div class="post-metadata">

**Author:** ![jerome](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/jerome/32/22_2.png) [@jerome](https://forum.babylonjs.com/u/jerome)\
**Post date:** [December 7, 2019, 6:09am UTC](https://forum.babylonjs.com/t/optimizing-the-scene-for-a-huge-amount-of-simple-meshes/7398/8 "2019-12-07T06:09:52Z")

</div>

and anyway, for the still selected meshes, use the boundsphere\_only culling strategy  
[https://doc.babylonjs.com/how\_to/optimizing\_your\_scene#changing-mesh-culling-strategy](https://doc.babylonjs.com/how_to/optimizing_your_scene#changing-mesh-culling-strategy)

it increases by far the selection time of evaluateActiveMeshes()

when using instances, use instanceArrayBuffers and skip the instance WM matrix automatic computations for immobile instances : [Mesh - Babylon.js Documentation](https://doc.babylonjs.com/api/classes/babylon.mesh#manualupdateofworldmatrixinstancedbuffer)

another approach : if lots of certain meshes don’t move each frame, you can also merge them in a SPS [Solid Particle System - Babylon.js Documentation](https://doc.babylonjs.com/how_to/solid_particles)

---

<div class="post-metadata">

**Author:** ![Mykyta\_Fedorovskiy](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/mykyta_fedorovskiy/32/3741_2.png) [@Mykyta\_Fedorovskiy](https://forum.babylonjs.com/u/Mykyta_Fedorovskiy)\
**Post date:** [December 13, 2019, 10:15am UTC](https://forum.babylonjs.com/t/optimizing-the-scene-for-a-huge-amount-of-simple-meshes/7398/9 "2019-12-13T10:15:34Z")

</div>

Hey guys,

thank you very much for your help. With your tips I managed to nearly tripple the frame rate. This was very helpful!!!

I also wanted to share my strategy a bit (may be useful for someone):

As suggested by @Evgeni_Popov in the first post I influence babylons culling strategy:

- After spawning an object as a rack ( = lots of paranted & instanced meshes) I do the following: (1) I refreshBoundingInfo (2) and then doNotSyncBoundingInfo & freezeWorldMatrix.

- My objects are mostly a composition of different paranted meshes. The bounding information is refreshed as suggested here: [[solved]how to get boundingbox info of a parent mesh with all children size - Questions & Answers - HTML5 Game Devs Forum](https://www.html5gamedevs.com/topic/30842-solvedhow-to-get-boundingbox-info-of-a-parent-mesh-with-all-children-size/)

- My custom culling strategy works as follows:

Thanks again 👍 👍 👍 !

---

<div class="post-metadata">

**Author:** ![zhang](https://avatars.discourse-cdn.com/v4/letter/z/aeb1de/32.png) [@zhang](https://forum.babylonjs.com/u/zhang)\
**Post date:** [December 14, 2019, 9:41am UTC](https://forum.babylonjs.com/t/optimizing-the-scene-for-a-huge-amount-of-simple-meshes/7398/10 "2019-12-14T09:41:43Z")

</div>

Can instance buffers be transparent?
