Optimise BabylonJS for a node link application

I am new to BabylonJS so grateful for any advice here.

I’m working on a node/link graph visualisation and analysis application in Java using OpenGL and looking to write something similar for the browser and use WebGL. The BabylonJS library was something we’d ideally like to use - it has an impressive API, great community support and Playground is also brilliant. Not needing to drop down into WebGL and deal with WebGL v1/v2 and browser support etc is also a plus given BabylonJS already handle this for us.

Based on testing so far rendering a graph of 40 thousand nodes and 40 thousand links seems to be extremely slow around 25 FPS. We’ve tried turning off lighting and rendering squares instead of spheres but it does not seem to help. The audience for the application is for data scientists so we don’t mind if it doesn’t have shadows for instance.

Some other things I need to have is icons on nodes and text underneath nodes as labels. However we are not sure how well all of this is going to be given the FPS we are seeing without the additions.

My questions are whether anyone is currently using BabylonJS for node link visualisation of large (40k) graphs and whether there are ways to turn off parts of the engine that might be slowing things down?

For instance, have a look at Babylon.js Playground to give some context.

Now have a look at Babylon.js Playground (and please zoom out to see the graph). In this example we’ve tried to use billboards and simple lines to mimic connections. If you change to for loops to be 20x20x20 you will see the FPS slow down.

Is there any techniques or ideas to improve the performance at around 40k nodes and links?

Many thanks in advance for reading this question and suggestions.

Welcome aboard!

You are having way too many draw calls in your PG. That’s because you create a new mesh line for each connection, resulting in 40000 meshes and 40000 materials too (each line has its own material).

You should create a LineSystem instead: this way, you will create a single mesh and a single material.

Also, with that many meshes (40000 boxes) you should freeze the active meshes, else the system is looping over all the meshes each frame. That means the system won’t determine which meshes are in the frustum and which are not, so you should set alwaysSelectAsActiveMesh = true on all meshes to be sure they will always be drawn. Call freezeActiveMeshes() with true as the parameter to avoid looping over the world matrices each frame.

You can also set isPickable = false to gain some perf.

Here’s a PG with those changes:

https://playground.babylonjs.com/#6M5PLA#2

You may also consider using thin instances (Use Thin Instances - Babylon.js Documentation) for better performances.

1 Like

Hi @Evgeni_Popov many thanks for the reply and update. I’ll keep having a play; but those changes have drastically improved performance thank you.