I'd like to add some practical perspective to this.
Let me preface that I'm operating on limited information here:
- I don't know how many objects you are dealing with.
- I don't know what exactly your acceleration structure is used for. Frustum culling? Ray tracing? Collision detection between objects in the BVH?
Going forward I'm going to assume you are talking about frustum culling a few thousand objects.
The number of objects will be too large to render without a hierarchy,
but for the same reason I expect building the hierarchy to be time
I'd argue that if you have to visit every object every frame in order to calculate a BVH, culling them directly and without a BVH is actually faster.
This of course depends on your frustum culling implementation. The bounding volumes of all objects should be stored contiguously in memory. This results in more efficient CPU cache utilization and allows for further optimization using SIMD instructions.
DICE has a whole presentation on this subject: Culling the Battlefield: Data Oriented Design in Practice
The presentation also mentions speeding culling up even more, using a simple grid.
Since I assume most 3D/simulation/game code bases already have some kind of BVH class and I don't know how critical it is for you to get the BEST culling performance, I'd like to present some arguments for sticking with a BVH:
Depending on what method you use, constructing a BVH can be fast and simple.
My current implementation of a binary BVH (each node can only have zero or two children and each leaf node only stores one item)
that is designed for quick construction takes around 0.18ms for 1137 objects on a single thread of an i7-5960X @ 3.89GHz. I'm sure it can be faster.
Construction is performed without reallocating memory in the process (this doubled the construction performance).
While SAH might generate the best BVH, it takes a long time. SAH is good for things you can precompute, like collision meshes.
At runtime you can then put the collision meshes into a BVH that is more suited for real-time construction.
A fast and simple BVH construction approach (the one I'm using currently) is to sort all objects on an axis (for example the parent AABB's longest axis) and split the collection in the middle.
To speed things up even more, calculate the node AABBs AFTER constructing the tree, by combining the two child node AABBs of a parent node. This avoids iterating through all objects (another 2x speedup). This however is only possible if your splitting criterion doesn't rely on the parent's AABB.