Should I break a large GAS into multiple smaller ones?

I am rendering a scene in OptiX where I am moving a camera through a large mesh scene.
Some of these triangle meshes are very large and cover most of the scene. Will I get any performance benefits by breaking the very large meshes into multiple smaller ones, or will OptiX do it internally?

I guess I am asking if OptiX creates multiple BVH nodes for a single mesh? Because if it doesn’t, then I guess there might make sense to break a mesh that are very large (at least compared to other meshes) down into smaller ones to increase performance when only a small portion of that large mesh will be hit by rays.

Hi @matias.christensen, welcome!

I don’t quite understand the multiple nodes part of the question, but I think we can clarify. First, you know this already, but just to orient together on the terminology… typically a scene BVH consists of a root node Instance Acceleration Structure (IAS), that points to one or more Geometry Acceleration Structures (GASes) and sometimes to child IASes. OptiX handles building the internal hierarchy of the IAS and GASes for you, while you are responsible for organizing the ‘external’ structure that combines the IAS and GASes together. OptiX does not change the structure of a GAS+IAS hierarchy that you create manually.

So you don’t need to worry about the internal structure of a GAS or IAS, but you do need to pay attention to the structure of the scene, and the instances in the scene. The primary performance consideration is whether you have multiple GASes that overlap spatially. If you have two GASes that overlap substantially, then rays cast against the scene IAS may need to traverse both GASes separately.

If you do have multiple GASes that overlap, then yes breaking meshes into smaller pieces can help - as long as that helps resolve the overlaps. In that case you might end up needing to use a multi-level scene which means using child IASes under the scene root IAS. There is a small cost to each extra level of IAS hierarchy in the scene, though if it resolves considerable overlap, there should be a net benefit.

Another option is to flatten the scene down to a single GAS, meaning put all triangles for all meshes into a single call to optixAccelBuild(), which will give you a more optimal acceleration structure without any overlaps but at the cost of losing your scene-level hierarchy. Flattening might change how you need to identify different instances when it comes to shading, and flattening might increase your memory usage if you were using multiple instances of any single mesh in the scene. Flattening might slow down BVH builds for animated scenes, since the whole scene GAS may need to be rebuilt. So flattening is not always advised, but when it’s feasible and convenient, flattening is usually good for traversal performance.

So, the answer to your question comes down to how much overlap there is between the multiple GASes in your scene. If you already have only 1 GAS, then you don’t need to break it into smaller pieces. If you have only small amounts of overlap, or only a few GASes that overlap, it might not be a major concern. If you have considerable overlap, large areas of space where any given point is inside two or more GASes, areas that will see heavy ray traffic, then it may help a lot to break down the meshes into smaller pieces.

An example: a scene with a GAS containing an unfurnished building mesh that also has GAS instances of furniture placed inside it will be slower to trace than if you use a GAS instance for each wall/ceiling/floor panel separately so that the GASes of furniture and appliances aren’t spatially overlapping the GASes of the building itself.