[Ray Tracing] How do you handle rapidly changing scene with high efficiency?

Hello colleagues, I’m very curious about how you handle rapidly changing scenes in real-time ray tracing?

I’ve tried OptiX to render several ray-tracing-enabled pictures with very high efficiency, while I noticed that constructing the acceleration structure (BVH Tree) costs a lot of time than executing the ray tracing pipeline.

So, if I want to enable ray tracing in an interactive game, where the position and velocity of objectives in the scene may change very fast (like shooter games with scenario destruction), how can I use OptiX with efficiency? Do I need to reconstruct the acceleration structure for every frame? If I do not, how does OptiX handle this scenario with efficiency? Thanks!

This depends on how your scene is organized, what is moving, how much things move each frame, what kinds of motions are occurring.

Here are a few small hints. You can definitely find some in-depth descriptions of these things by searching previous threads, but you are welcome to add details about your goals and ask follow up questions as well.

If you have many instances that change position & orientation but are not changing shape, i.e. all the motion is rigid body transforms, then for high efficiency, you should use instancing [1] to build a GAS around each individual mesh, and an IAS to put all the meshes/instances into the scene. Each frame you will need to rebuild the IAS, but you don’t need to rebuild any GASes unless they are changing shape or have non-rigid transforms (for example, the vertices of a mesh are moving relative to other vertices in the same mesh). It is typically much faster to update or rebuild an IAS than to rebuild the geometry portions of the BVH.

If you’re not adding ore removing geometry or instances in any given GAS or IAS, then you have the option to “update” the acceleration structure rather than “rebuild” the BVH from scratch. See the ‘dynamic updates’ section of the Programming Guide [2]. This will work very well when all instances or geometry moves in the same direction, but if the motion is scattered and many moving things cross paths, then the performance of the BVH will go down over time, so you may have to rebuild your acceleration structure after a few frames in order to keep performance at an acceptable level. This might allow you to do updates on most of your accel structures, and choose a subset of ASes to rebuild each frame. Here are a couple more threads on this topic, and a video I’ve done discussing update vs rebuild strategies for moving curves - the concepts here are relevant to what you’re doing even if you’re not using curves. [3][4][5]

[1] https://raytracing-docs.nvidia.com/optix8/guide/index.html#acceleration_structures#instance-build-inputs
[2] https://raytracing-docs.nvidia.com/optix8/guide/index.html#acceleration_structures#dynamic-updates
[3] Updating AS leads to extremely low traversal performance - #6 by dhart
[4] Optix Dynamic Geometry Unstable Rendering FPS - #2 by dhart
[5] OptiX Advanced Topics | NVIDIA On-Demand


Thanks for your patient reply! I will get a quick look on the given materials!

My GLTF_renderer example described here https://forums.developer.nvidia.com/t/optix-advanced-samples-on-github/48410/16 supports SRT rigid body animations, morphing, and skinning now.

The SRT animations only require updates to the top-level IAS instance matrices.
Morphing and skinning also require updates to the affected GAS.

The AS building happens inside the two functions buildDeviceMeshAccel and buildInstanceAccel
both functions pick the build flags and operation depending on the rebuild and animation state.
Non-animated AS are built for better tracing performance and compaction, animated AS prefer fast build performance and no compaction. It’s not rebuilding in regular intervals.

For the amount of work which happens during the morphing and skinning operations which are currently still handled in a single CPU thread, it’s working pretty well.
Those calculations would become a lot faster when moving the morphing and skinning calculations onto the GPU, which is on my todo list.
Unfortunately due to CMake bugs, that requires to separate the application into its own standalone solution which requires some administrative changes to the example framework.