How can I optimize meshes for over 20,000 cubes?

Hello everyone

there are 20,000 cubes in my Block Model, and I used the instance to optimize it but I need much more optimization to get the smooth rendering,
here is my PG: https://www.babylonjs-playground.com/#ZEZLAT#51
is it any way to improve it?

1 Like

There are a lot of ways how and where optimize your scene for the smooth view.
Did you try any of optimization hints which are described here? - Optimizing Your Scene | Babylon.js Documentation

3 Likes

Hi @labris
Thank you for your recommend , I use all of the method in documentation, but I couldn’t get the desire speed. there is one important limitation in my Model, which I need all the cubes bounding boxes, and I should render about 20,000 cubes with their bounding boxes. I used the instance to improve the model, but it’s not enough. its only works smooth for less than 6000 cubes.

I suppose you have very special application.
If there are no ways to reduce the number of meshes (which is the main bottleneck) you may try to limit render framerate.
So, you managed to smooth render about 6000 cubes; if you will render them only every 4th frame, you should be able to have quite smooth render for about 24 000 cubes.

Thank you so much for your recommend.
How can I limit the render frame rate?

I used following code for limit the render frame rate, but again there are lag.

  window.setTimeout(() => {
    engine.stopRenderLoop();
    let lastTime = new Date().getTime();
    window.setInterval(() => {
      scene.render();
      let curTime = new Date().getTime();
      fpsLabel = (1000 / (curTime - lastTime)).toFixed() + " fps";
      console.log(fpsLabel);
      lastTime = curTime;
    }, 10);
  }, 1000);

The simplest example is here - https://playground.babylonjs.com/#3A2PUF#2
It renders the scene only when pointerDown.
Another example with RollingAverage - Babylon.js Playground
But without knowing your specific application it is difficult to give you the exact answer.
This subject has a lot of discussions, so I would suggest you to search first; and, then, to find the best method for your case.
Here just a couple of links - there are dozens of them:
What's the difference between engine.getDeltaTime and scene.getAnimationRatio? - Questions - Babylon.js
Decoupling Frame rate from movement speed issues - Questions - Babylon.js
Which Best Method for Mesh Rendering (Updated Every Frame) - Questions - Babylon.js
From old Forum - Controlling the render loop - Questions & Answers - HTML5 Game Devs Forum

2 Likes

Thank you so much for your help :pray: :pray: :pray: I am going to search and learn much more about this topic.

1 Like

Hi @Necips, Thanks a lot for your recommend , but I didn’t understand how can I calculate the data beforehand.
In my model I get the data with the json file, and how can I calculate it beforehand. is it possible to give me some hint how can I do it?

Here are some hints for so called Object Pool - Object Pool · Optimization Patterns · Game Programming Patterns
They don’t relate to JS or Babylon directly, but to know all these tips is very useful because they explain the logic inside your application.

2 Likes

Thank you so much @labris for devoting your time to answering my question and helping me to increase my knowledge. :pray: :pray: I’m going to read this article. :pray: :pray:

2 Likes

Maybe try using LOD to change the cubes to a lower detail mesh, e.g a plane at a certain distance. Or to not render them completely if far enough. Check this link

2 Likes

Thank you for your recommend :pray: :pray:

Thank you so much, its a great idea :pray: :pray:
I am going to work on it.

should I do it in the following format? I didn’t understand what should I do with time , should I set interval for each mesh separately?

scene.registerBeforeRender(function () {
for (let i = 0; i < cubes.length; i++) {
  let instance = cube.createInstance("cube" + cubes[i].key);
  instance.position.x = cubes[i].X;
  instance.position.y = cubes[i].Y;
  instance.position.z = cubes[i].Z;
  instance.instancedBuffers.color = new BABYLON.Color4(
    0.3,
    0.4,
    cubes[i].G
  );

  avgX += cubes[i].X / cubes.length;
  avgY += cubes[i].Y / cubes.length;
  avgZ += cubes[i].Z / cubes.length;

  arrCubes.push(instance);

  //************** End Fetch Cubes **********/
}

  });

I don’t know your application much, but I know that Thin Instances can definitely handle 20,000 easily. You will lose bounding boxes, but I guess you would have to write more code to make up for that.

2 Likes

Thank you so much for your explain :pray: :pray: :pray: I will try to find a way :pray:

I need each mesh separately because I have a Gizmo box which move through the block model and deleted the cubes that are inside the Gizmo box.

I think it is difficult , However it’s great idea. I should work on it. :pray: