New feature: BoundingInfoHelper

Hey team!

I’m pleased to announce a new feature for you folks to test: The BoundingInfoHelper!

This class is meant to let you tap into the GPU to compute the bounding box of a list of meshes.

As you know, by default, Babylon will update the bounding box on every frame but only by applying the new world matrix, As the bones and the morph targets are applied on the GPU during rendering the CPU has no clue about how to extend the bounding box to take them in account.

That could be a problem for picking for instance, if you want to quickly select a mesh based on its bounding box (same for collisions, occlusions, etc…).

Up to now the only way to get an accurate bounding box was to call mes.refreshBoundingInfo(true, true). That function was not something we recommended using on every frame as it could be very slow if your mesh has a lot of vertices.

That’s why we decided to introduce the BoundingInfoHelper. That class will also update your bounding info but by using the GPU this time.

For WebGL2, it will use a transform feedback shader.
For WebGPU, it will use a compute shader.

Demo:

On that specific demo, I’ve got the following results:

  • CPU: 38ms
  • WebGL2: 15ms
  • WebGPU: 10ms

so almost a factor of 400% for compute shader!

Doc: Bones and Skeletons | Babylon.js Documentation (babylonjs.com)

Enjoy!

21 Likes

Does this mean that vertexData.applyToMesh will no longer freeze the main thread when creating large meshes on the fly? Man that’s exciting!

Unfortunately no :frowning: this is not related to setting mesh geometry data

More demo:

WebGL2 demo (using transform feedback): https://playground.babylonjs.com/#QPOERJ#9

WebGPU demo (Using compute shaders): https://playground.babylonjs.com/#QPOERJ#10

3 Likes

Isn’t the bounding info computed on the cpu when setting geometry data? I thought it could be another application for this new technique :thinking:

It is but when you see the lag in apply it is when we send the mesh data to the GPU

1 Like

I love how out of nothing there is suddenly this huge performance boost :astonished: And like in rappid fire mode right after the GPU picker. Thanks for having a heart for all the well aged computers out there :heart_eyes:

1 Like

I’m glad you liked it :smiley:

Is it possible to segment the bounding box into multiple bounding boxes, so you get from top to bottom as many chunks as you like, which shows you a more accurate shape?

That’s not supported by this feature. That would imply splitting the mesh into submeshes (Well this is kind of supported if your mesh has already submeshes set up because in that case each submesh will also have its own bbox)

1 Like

I will try to do an experiment, but basically the mesh would not be split up, it would be one irregular mesh from top to bottom, like a stack of jenga with parts coming out of each side, on the Y Position.

The top of the mesh might be wider than the bottom.

I would have to split the mesh up by the vertices to achieve what im describing, with the current system, right?

I only mention this because of the dynamic nature of this bbhelper on animated objects, so it had me think why not segment it for a further detailed bbox

1 Like

Correct

I’m benchmarking BoundingInfoHelper on Chrome and Firefox against Seedborn stress test scene on dev under webgl2. The helper runs on a callback every frame for the animated farmhands only. Farmhands are clones with a materialPlugin. On average, each farmhand is <500 verts with about 50 bones. My code diff is:

new: await _this.game.BBHelper.computeAsync(_this.srcMesh);
old: _this.srcMesh.refreshBoundingInfo(true);

which is a one-liner change. I need to stress that there are no other edits, I only comment/uncomment to use 1 or the other. Below is the perf snapshot for v8.0.3.

I wait for the scene fps to stabilize somewhat b4 the screen capture. The control case is no BoundingInfoHelper, ie, the default refreshBoundingInfo(true). BoundingInfoHelper appears to be consistently worse across the 2 browsers for me. Maybe my use case isn’t the best use of the helper or the transformFeedback isn’t performant or other interactions causing the hit.

Not trying to diss the new stuff, I was looking forward to the perf gain. But shrugs…
Hope this helps.

Do you see a gain in these PGs?

WebGL2 demo (using transform feedback): https://playground.babylonjs.com/#QPOERJ#9

WebGPU demo (Using compute shaders): https://playground.babylonjs.com/#QPOERJ#10

If this is the case, the lower performance you are experiencing may be due to the fact that you have too many meshes with too few vertices, and that the time required to send the data to the GPU cancels out any performance gain.

chrome (useGPUCompute false): ~60 to 80ms (webgl2 pg), ~70 to 100ms (webgpu2 pg)
chrome (useGPUCompute true): ~20 to 30ms (webgl2 pg), ~20 to 30ms (webgpu2 pg)

Understood, its a trade off then. Guess its not for my use case, thanks for the insight! I’ll keep in mind.

1 Like