Blog Post: Improving Performance in BabylonJS

In case anyone is interested, here is our experience with attempting to optimize the performance in our Babylon game :slight_smile:

Thanks to @Evgeni_Popov and others for their assistance with this!

13 Likes

Very interesting thanks !

When struggling with mesh selection, with a project that allows it I often use this kind of solution,

let selectablesMeshes: BABYLON.AbstractMesh[] = [];
// keep selectablesMeshes up to date, it should contain all selectable meshes in your scene

let bestDist: number = Infinity;
let bestPick: BABYLON.PickingInfo;
let ray = this.scene.createPickingRay(x, y, BABYLON.Matrix.Identity(), this.scene.activeCameras[1]);
for (let i = 0; i < selectableMeshes.length; i++) {
    let mesh = selectableMeshes[i];
    if (mesh) {
        let pick = ray.intersectsMesh(mesh);
        if (pick && pick.hit && pick.pickedMesh) {
            if (pick.distance < bestDist) {
                bestDist = pick.distance;
                bestPick = pick;
            }
        }
    }
}

It works very well when only some meshes are selectable and you don’t want the engine to do Ray/Mesh intersection on the non-selectable ones (like environment props).

Alternatively, in your case you work with tiles, so there’s probably some optimisation relying on that (like : do an intersection between Ray and Ground, know the tile IJ you aim at, then check for intersection only around this tile).

Thanks again for you research, have a nice day !

1 Like

Nice post!

Regarding:

I was under the impression that babylon’s skeleton animations were computed on the GPU

The doc is not clear, I updated it (Make clear that bone matrices are not computed on the GPU by Popov72 · Pull Request #1042 · BabylonJS/Documentation · GitHub). Bone matrices are not computed on the GPU, they are computed on the CPU. It’s only the transformation of the vertices by the bone matrix which is done on the GPU.

Thanks for this. This may be a better way to detect when the pointer is over an HtmlMesh than the current scene.pick with a predicate I am using.

im a bit confused by this, so how then do you tell the scene to change what it consideres “selected”?

Also what happens when visibility changes?

Im also getting really odd issues like rotations being wrong when cloning from an asset container etc which go away when I turn off freezing.

IMO the whole way mesh selection and freezing works needs needs an entire rethink because right now I wont be using BabylonJS in another project because of this, its too much of a headache.

Thanks for the post!

I tend to agree with this.
For my project I know exactly which meshes should be rendered or not, which I let the engine know via the visible or alpha property, so in theory selecting meshes then should not take much time.
Freezing active meshes is not feasible for me at all because of constant visibility changes/new meshes.

I have planned to overwrite some babylon code to keep a cache of active meshes myself, but as mentioned in the blog there are often more important things to do :slight_smile:

Reading your post, I think there is some overloading of the term “mesh selection” that is causing some confusion. In your blog, mesh selection seems to refer to active mesh selection, which meshes needed to be rendered. Whereas I think Sven’s comment and mine was referring to picking a mesh (when a user takes some action and we need to know what mesh they picked).

Love your game BTW. Very cool art style and fun mechanics.

Yes, when I am referring to mesh selection I am referring to the metric that Babylon records as mesh selection. This is “Frustrum Culling” step that babylon does (as far as I understand it).

So no I am not referring to picking which is what I think you are referring to :slight_smile:

So I implemented Sven’s suggestion for picking thinking it would make a difference because I wouldn’t be testing every mesh. It turns out it doesn’t if you have to use a predicate to filter the meshes that are selectable anyway. I guess that makes sense because using scene.pick iterates over all of the meshes applying the predicate to determine if it cares abut the intersection. If you have a separate list of meshes, you can save yourself the time to execute the predicate, but chances are you’ll still need to check something (e.g. is the mesh enabled), so it probably makes no difference.

Yes my bad, I re-checked the use case for which I implemented this, and it’s in fact more specific than just “Mesh Selection takes too much time”.

(on a 1st person view, minecraft-like, with a terrain divided in a lot of chuncks, I wanted to compute each frame where the player was aiming at in a close range when he’s adding a block : so keeping track of the nearest 9 chuncks was easy to do, and prevent going through all scene meshes each time)

And sorry Mickey for misunderstanding the meaning of “Mesh Selection” in your article and diverting your topic !