Queries Against Union Geometries (Particles with multiple shapes/geometries) Do Not Utilize BVH

Our project utilizes lots of static geometry to build our maps, which creates a ton of memory usage in physics in Chaos’ acceleration structures. In an effort to combat this, we’ve been clustering a lot of static physics geometry into singular particles to reduce memory usage pressure within the acceleration structures. This gave us quite a bit of memory savings, but gave us performance issues that was more than we’d expect given that union objects in Chaos have a BVH structured constructed for all the shapes and geometry it contains.

Upon closer inspection, queries (like raycasts, sweeps and overlaps) do not utilize this BVH at all. The raycast/sweep/overlap functions for union objects will iteratively go through each object it holds, but those functions are not even utilized (at least with the base particle). Primarily, TSQVisitor::Visit will grab a shape array from the particle and iteratively go through each shape to test against it. This is fine for unions with 10 geometries, but we have clustered particles that typically number around 500 geometries.

Is this intended? It’s hard to imagine we’d have a BVH that gameplay queries won’t even utilize.

[Attachment Removed]

Steps to Reproduce

  1. Create a static mesh asset with multiple collision geometry
  2. Place into scene, have something do a raycast/sweep/overlap check against it.
  3. Place breakpoint in TSQVisitor::Visit to see it test against the shape array iteratively
    [Attachment Removed]

Adding some perf numbers for context, which is based on a query stress test that sends 4000 raycasts and sweeps at the player’s position.

Control (no union geometries, everything in the base acceleration structure): 17ms

Clustered Bodies (union geometries with 400+ shapes): 28ms

Clustered Bodies + BVH traversal on union geometries from physics queries: 18ms

My implementation might not be the most performant as the changes were made to facilitate merging into newer UE versions but utilizing the BVH for queries almost eliminates the cost of physics queries against them.

[Attachment Removed]

Hi Ali, and thank you for your question.

Apologies this has taken a while to respond to.

I’d like to dig into this answer by beginning at an earlier point, since you describe this as a workaround for memory issues.

Did you get a good read on where the memory costs were coming from?

Have you also implemented ISM for the geometries if there are multiple instances of the geometries?

I’ve heard of people adding a number of geometries to a body, but I’ve not really heard of the numbers you describe. Most cases this number is pretty low, and wouldn’t have need of the overhead of an acceleration structure.

Best

Geoff Stacey

Simulation, Developer Relations

EPIC Games

[Attachment Removed]

Hi Ali,

The quick answer (and one you alluded to above) is that this is a path which we haven’t really felt the need to optimize since it is an edge case.

There’s a bit to unpack with this - but firstly you are correct that our memory usage can be on the high side. From taking a dive into this from other tickets, one of the main things which can cause additional memory is actually our allocators. They will frequently reserve 8 elements and only use 1 when growing arrays for example. With the alterations you’ve made, this is sidestepped because you are using a far larger array allocation.

If you take a look in the ‘GenerateTree’ function of AABBTree.h and add the below code at the end of that function you may be able to save memory here

(using TLeafContainer::TArray::Shrink;) - add this in the usual part of the file

//add these at the end of the GenerateTree function

Leaves.Shrink();

Nodes.Shrink();

ISM’s themselves are pretty efficient in terms of memory in Chaos - we only need to store the mesh data once, and then each instance only needs to store the transform (assuming a convex mesh). The ‘particle’ cost you mention could be what I describe above.

Depending on your map setup as well, commonly clients will sidestep the memory issue by simply not adding the actor to the scene unless it is needed (ie in large worlds, you can just have a lightweight mesh proxy with only render information, and ‘hydrate’ the actor when it need to be interacted with).

Light Weight Instances UE5 | Community tutorial is a good article made by the community explaining this further

All the best

Geoff

[Attachment Removed]

Hell there,

Sorry to bump in but I’m interested by this topic too.

Indeed we have similar setup with one ISM containing sometimes a thousands instances.

It seems much more cheaper on CPU side to create/load/unload and also to teleport one physics body with 1000+ shapes than 1000+ actors with only one shape.

The memory saving is interesting too, even if not our top priority.

So merging all shapes into the same body instance seems a good improvement for us too, but I’m also concerned by this lack of acceleration structure (i.e middlephase) at actor level. I know there is one for trimesh but we’d like to keep our simple geometries here.

Finally we have similar needs too, so I’m not sure that is much an edge case (e.g having big building made of assemblies of simple shapes geometries).

  1. Is there any plan to add acceleration structure at that level ?
  2. Do you have any recommendation for such setup ? is recommend limit for max number of shapes per actor ?
  3. I guess collision detection is impacted too, so it’s not only about queries ?
  4. anything else ?

Thanks a lot for helping

[Attachment Removed]

Hi Romain, and no worries about adding input to this ticket - we are always interested in hearing how clients are using Chaos.

Would you be able to open a specific ticket for this though please - there are a few follow up questions I have about the workflow side - we can always link that ticket here so other people can follow.

Thanks!

[Attachment Removed]

We also noticed that a mesh with many ConvexElems (>=64) and the query just iterate over them instead of using any acceleration structure which costs too much perf.

Is there any other ticket following up the query performance issue?

[Attachment Removed]

Hi there and thank you for your question. Apologies this has taken a while to respond to.

As a general answer you’d have to extend the engine in order to support using a BVH for scenequeries. We do use the BVH for the collision side (since the simple collision shapes are used commonly for collision detection), but the common shape for scenequeries is a tri-mesh. It is something which is a good idea, and we are interested in implementing it - but there is no timeline for when we’d be able to do this.

Specifically for lots of static geometry and scene queries, it may be best to create a trimesh for this (unless you are under large memory constraints), or alternatively keep the shapes broken up amongst bodies, but use something like world partition and/or lightweight actors to reduce the physics cost between the game and physics thread.

Best

Geoff Stacey

Developer Relations

EPIC Games

[Attachment Removed]

We observed a lot of memory usage coming from acceleration structures and general per particle costs. Our levels had a high particle count based on how many meshes we were using to build out the scene. We use a plugin called MeshPack that would automatically convert static mesh actors into ISMs when we cook, but I’m not sure what that would do to help our physics memory usage as I’ve observed that we’re creating a particle per instance anyways.

I would imagine it is unorthodox to create these high geometry count bodies, but their BVH structures are a lot less memory intensive vs TAABBTree and we’re already paying for the cost of creating these BVH structures for these bodies. We’ve seen our physics memory usage cut down almost by half utilizing these clustered particles. The negative of this approach was the performance impact of physics queries, which is resolved by utilizing these BVH structures that are by default constructed for union particles.

[Attachment Removed]

There is an acceleration structure made for these combination of shapes and used for the middle phase, the issue is it isn’t using it for queries at all.

[Attachment Removed]

ISMs and StaticMeshComponents don’t have any difference in Chaos memory usage from what I’ve observed; that would make sense to me as they’re both using the same body setup from the static mesh asset. We also already made the modification to shrink the Leaves and Nodes array, which had some marginal savings but no where close to our approach in clustering multiple particles into one.

Unfortunately, something like light-weight instances wouldn’t work for us. We need a large area loaded in at once as we have both AI and players that can be anywhere around the map, and there is an expectation they’d be able to interact with any geometry they can see. We’ve done some work on explicitly marking up which collision profiles to allow creation of particles on server and client to give us more savings.

[Attachment Removed]

Indeed I have recently noted that, thanks for confirmation.

[Attachment Removed]