I’m trying to write an Optix closehit program with dynamic geometry by loading new meshes for each frame. Then I notice that the rendering frame rate is not quite stable during geometry update, ranging from 1000FPS to 200FPS.
The updateAccel code is quite similar to the one provided in Optix SDK.
The most likely cause here is a degraded acceleration structure. This can happen when using the UPDATE operation when things move too far from their original position (meaning the position used for the last BUILD operation). The OptiX Programming Guide mentions a few different ways the accel structure can degrade during UPDATEs: https://raytracing-docs.nvidia.com/optix7/guide/index.html#acceleration_structures#dynamic-updates
How are you timing your render phase? Specifically is it synchronous or asynchronous, and are you using CUDA events or a host-side timer? These framerates are still high enough, even when it slows down, that it could be worth double-checking that your timing code is correctly implicating the render phase and not something else.
BTW we’ve discussed a few different strategies for mixing BUILD and UPDATE operations in a GTC spring talk from 2021, here’s a link: OptiX Advanced Topics | NVIDIA On-Demand
One strategy is to re-BUILD your accel structure after every few UPDATEs. Another strategy is to pick the pose of your mesh very carefully when you BUILD so that it is less prone to degrading when you UPDATE. This can sometimes be achieved by doing the BUILD operation in your mesh’s most extended pose or shape, but this depends a lot on how coherent the motion of your mesh is over time. Other strategies might be to double-buffer your mesh builds, or to limit the amount of motion to a range that suffers less.
Thanks for your patience. For timing, I follow the optixDynamicGeometry example code in Optix SDK, and use chrono lib to calculate the CPU time after synchronization, the render phase mainly contains two operations optixLaunch && CUDA_SYNC_CHECK. The timing code block is like below.
Your comment mentions that the render is synchronized before marking your timer’s t1 end event. The thing to double-check is whether you synchronize after your deform() kernel, otherwise the t1 for deform() and t0 belonging to render() could be set before your deform() kernel has finished running.