Acceleration structure memory consumption

Hi, I was playing around with selector nodes for the purposes of animation and a question regarding memory consumption of acceleration structures came up.

For instance, I may have a fairly refined animation sequence of fairly high-poly meshes. Consequently, I expect that every mesh in the sequence will have a relatively complex acceleration structure that will be loaded to the device, which may or may not take up acceptable amount of memory (which is already taken up by the vertex data of the meshes).

Is there a way to find out how much GPU memory acceleration structures take up? I found getDataSize() method, but it returns suspiciously little size. Perhaps, I missed some profiling options in Nsight? Thank you for your time.

What kind of animation are we talking about?

Anything which can be expressed via affine transforms on geometry groups can be handled inside the OptiX scene graph without duplicating acceleration structures, where flattening the hierarchy to reasonable levels is recommended.

Querying acceleration structures for their size and data, which allowed storing and loading them in the past, has been deprecated since OptiX 4.0. Building the acceleration structures on the GPU is faster than loading them from disk.
[url]http://raytracing-docs.nvidia.com/optix/api/html/optix__host_8h.html#a2dd11c5b4c6eee732445e9a90d4666c3[/url]

You should be able to retrieve some more information about the memory consumption inside OptiX via the
rtContextSetUsageReportCallback functionality.
[url]http://raytracing-docs.nvidia.com/optix/api/html/group___context.html#ga35c7da345b942238a7ec4db8e2516955[/url]

OptiX 5.1.0 supports motion blur, which means you can actually provide it with either affine transforms or morphing geometry information at key-frames when the topology doesn’t change and interpolate between them per ray.
How that renders depends on how you specify the time at the key-frames and time per ray which can be read via the semantic variable rtCurrentTime.
An example of using that with affine transforms can be found in the OptiX Introduction example number eight.
[url]https://devtalk.nvidia.com/default/topic/998546/optix/optix-advanced-samples-on-github/[/url]

I’m guessing that the acceleration structure around that is most likely smaller than storing all frames individually under Selector nodes, if that is what you’re doing.

Generally I would not recommend using Selectors for new developments.

Thank you for the timely response! I have a heart animation, which happens to be a sequence of non-uniformly deformed meshes. Fortunately, the topology is preserved (i.e., vertex count, half-edge structure), which from what I understood means that I could give motion blur a try. That is very helpful.

Did I understand it right that a single acceleration structure is built over the entirety of all meshes that comprise the motion? It is likely that I may also have animation sequences that similarly can’t be expressed in terms of affine transforms and on top of that have large variations in the dimensions of the bounding boxes of the individual meshes, which may result in a large number of false intersections for certain key-frames.

Which is why I was wondering whether in certain cases I could simply exchange geometry children nodes (key-frame meshes) of, let’s say, a certain optix::Group animated_group. The assumption would be that a child geometry node has its fine acceleration structure built once, and then when the exchange takes place, we simply update bbox of animated_group and rebuild (refit?) coarse acceleration structure of the parent node of animated_group. And then maybe a trade-off between rebuilding acceleration structures and reducing the number of false intersections may end up in favor of the former approach. Conceptually:

optix::Group animated_group = context->createGroup();
animated_group→setAcceleration(context→createAcceleration("Bvh")); 
animated_group→setChildCount(0); // its one child node will  keep getting changed
top_group→addChild(animatedgroup); // top group created earlier
...
animatedgroup->setChild(some_geometry_group); // some_geometry_group - holds key-frame mesh and has its acc structure built beforehand 
animatedgroup->getAcceleration()->markDirty(); // update bbox of animatedgroup
top_group->getAcceleration()->markDirty(); // rebuild coarse structure taking updated bbox of animatedgroup into account

The question is, what happens when I exchange one child node (some_geometry_group) of animated_group with another? Does it get unloaded from the device (its fine acceleration structure gets destroyed, I presume)?