How many keys should be defined for motion instance AS?

I have read the Motion Instance Acceleration Structure section of the document carefully. But I still have some confusion.

  1. What does the number of keys of motion IAS affect the traversal performance? What does the number reflect? In the optixSimpleMotionBlur example, there are two instances which reference triangle mesh and sphere mesh, respectively. They both have 3 motion keys, while the number of motion keys of the motion IAS is set to 2 and the values of motion keys are not set. Why is this?

  2. I still do not understand how to define the number of motion keys of IAS. It is described in the document that Finally, the quality of the instance acceleration structure is also affected by the number of motion keys of the referenced traversables of the instances. So how does it affect? For example, a referenced motion transform has 3 motion keys and the other motion transform has 2 motion keys. How do we define the number of motion keys for IAS to get good performance now?

Thanks in advance.

Hi @novice!

They both have 3 motion keys, while the number of motion keys of the motion IAS is set to 2 and the values of the motion keys are not set. Why is this?

I see 2 matrices used for keys for the IAS in optixSimpleMotionBlur - these 2 matrices are the key values. Is that what you meant? Maybe I misunderstand the question.

How do we define the number of motion keys for IAS to get good performance now?

The IAS in this case has a linear motion, so it only needs 2 keys. In general, you should use the fewest keys you need in order to represent your motion, that’s all the Programming Guide is trying to say. Adding more keys tends to slow down traversal, so don’t use more keys if you don’t need them. The paragraph above the one you quoted outlines the general criteria to keep in mind. If your motion is linear, then only use 2 keys.

The language is a bit vague because perf always depends on the scene itself, and because we aren’t recommending you should avoid using more keys if you need more keys. Use as many keys as you need, just no more than that. It’s just clarifying that motion keys aren’t free, so treat them like any other resource and try to balance it by minimizing the cost while maximizing the quality.


David.

Related topic: https://forums.developer.nvidia.com/t/optix-motion-blur-with-multiple-key-frames/168164

Also note the link to another motion blur example inside the second post.

Sorry for the mistake. In the optixSimpleMotionBlur example, the triangle mesh and sphere mesh have 3 and 2 motion keys, respectively.
Triangle:

......
//
// copy triangle mesh data to device
//
const int NUM_VERTS = 3;
const std::array<Vertex, NUM_VERTS*NUM_KEYS> tri_vertices =
{ {
      {  0.0f,  0.0f, 0.0f, 0.0f },  //
      {  1.0f,  0.0f, 0.0f, 0.0f },  // Motion key 0
      {  0.5f,  1.0f, 0.0f, 0.0f },  //

      {  0.5f,  0.0f, 0.0f, 0.0f },  //
      {  1.5f,  0.0f, 0.0f, 0.0f },  // Motion key 1
      {  1.0f,  1.0f, 0.0f, 0.0f },  //

      {  0.5f, -0.5f, 0.0f, 0.0f },  //
      {  1.5f, -0.5f, 0.0f, 0.0f },  // Motion key 2
      {  1.0f,  0.5f, 0.0f, 0.0f },  //

} };
......

Sphere:

......
const float motion_matrix_keys[2][12] =
{
    {
        1.0f, 0.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f, 0.0f,
        0.0f, 0.0f, 1.0f, 0.0f
    },
    {
        1.0f, 0.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f, 0.5f, // 改变了平移分量,向y轴正方向移动了0.5
        0.0f, 0.0f, 1.0f, 0.0f
    }
};

OptixMatrixMotionTransform motion_transform = {}; 
motion_transform.child                      = state.sphere_gas_handle;
motion_transform.motionOptions.numKeys      = 2;
......

But the motion IAS only has 2 motion keys.
motion IAS:

...
OptixAccelBuildOptions accel_options = {};
accel_options.buildFlags              = OPTIX_BUILD_FLAG_NONE;
accel_options.operation               = OPTIX_BUILD_OPERATION_BUILD;

accel_options.motionOptions.numKeys   = 2;
accel_options.motionOptions.timeBegin = 0.0f;
accel_options.motionOptions.timeEnd   = 1.0f;
accel_options.motionOptions.flags     = OPTIX_MOTION_FLAG_NONE;
...

There is no motion key values for IAS, only the accel_options.motionOptions.numKeys is set. I want to know where the motion key values for the IAS are and why the numKeys for the IAS is set to 2 (Because the triangle mesh has 3 motion keys).

I only see 2 matrices used for keys for the sphere mesh, which is the motion transform in code.

The used OptiX version is OptiX 7.6.

Please have a read through this chapter of the OptiX Programming Guide:
https://raytracing-docs.nvidia.com/optix8/guide/index.html#acceleration_structures#motion-instance-acceleration-structure
The last paragraph in that explains it.
The SDK example is probably using only two keys on the IAS because the motion is linear enough to not require more.

The point is that the more motion keys you use, the longer it takes to build the acceleration structure and the more memory is required. On the other hand the volume of the resulting AABBs might get smaller because the motion geometry can be enclosed more tightly.
Think of it like a convex hull around all motion geometry. When using too few motion steps in the IAS it might result in a bigger AABB than when using more motion keys.
The performance differences depend on the specific scene so it’s hard to predict results.
So it should all work fine when using the maximum number of keys as there are inside the underlying motion geometry and then you could try reducing it.

Thanks for you replay! I read the guide again but still have some questions.

Transformations like a simple translation, rotation around the center of an object, a small scale, or even all of those together are usually handles well by a two-motion-key instance acceleration structure.

For the above description in the document, what is the “simple” translation? Does it mean that two motion keys are enough if the transformations contain only translation (What about many translations with different directions)?

In addition, I still do not understand what different number of motion keys mean. For example, in the figure below, the square moves from point A to B and is associated with 4 motion keys. If we allocate 2 motion keys for the IAS, does this mean that the square’s motion is considered as a single process, whereas using 3 motion keys for the IAS suggests that the square’s motion is viewed as two separate processes?

what is the “simple” translation?

That sentence is trying to illustrate what the preceding sentence is saying about “the linearity of the motion”. “Simple” is being used to indicate that the motion is linear or approximately linear. If the motion is linear, then you only need 2 keys. If the motion is non-linear, then you need to decide how many keys to use to sufficiently approximate the motion. This is up to you to decide, based on your quality needs.

Note that the word “linear” is slightly tricky since OptiX supports matrices and SRT (scale, rotate, translate) keys. The key values are being interpolated linearly, but that doesn’t mean the resulting motion is actually linear in world space. This is why the programming guide is using words like “simple”. The takeaway message we’re trying to get across is just to try to be aware of how complex the motion is and whether your small number of keys is sufficient. The performance warnings are just there to say that it’s not the best idea from a performance and memory perspective to use a high number of keys by default.

On the left, you can match the intended motion using 2 keys because the motion is “simple”. On the right, the curved motion may require more than 2 keys because the motion is not simple enough.

In addition, I still do not understand what different number of motion keys mean.

Each object has it’s own independent motion, and you get to specify the timing of the keys. The keys for one of the GASes isn’t a subset or sub-process of the IAS motion, unless you setup the key timing that way. You can think of the final GAS motion in world space as being additive of the hierarchy’s motion, so if the IAS has 3 evenly spaced keys, and a child GAS has 4 evenly spaced keys that specify linear motion, and if the end keys of the interval match, you’ll really get 5 linear path segments, I think… Remember the ray has a time value attached to it, and each thing the ray traverses evaluates it’s own position in time independently, whether that thing is in the middle of the hierarchy or at the leaf.

Note dashed lines are intended to show correspondences in time. This shows the same time interval at the start and end, but a different number of keys for two items in the hierarchy, resulting in a more complex final world space motion than either of the moving nodes.


David.

Thank you for your thorough explanation; I now have a better understanding of the first question regarding the “simple” translation. The figures provided are indeed very clear.

Regarding the second figure, the IAS has 3 evenly spaced keys, and these keys possess values that collectively define a motion trajectory for the IAS. However, I am still a bit confused. In the optixSimpleMotionBlur example, there are no specified values for the motion keys of the IAS. Instead, only the accel_options.motionOptions.numKeys is set. Should values for the motion keys of the IAS also be specified in this scenario?

there are no specified values for the motion keys of the IAS

The motions themselves are handled by the OptixMatrixMotionTransform and OptixSRTMotionTransform traversable handles attached to the individual instances’ child field in the root IAS.

Maybe it gets clearer if you also look at the optixMotionGeometry example inside the SDK.

The root IAS doesn’t necessarily need any motion keys. It will build the AABB around its children anyway, irrespective of motion or non-motion instances inside it. It’s just a matter of how good the AABBs inside the IAS will be able to enclose the volumes covering the motion objects. So as explained inside the programming guide and above, using motion IAS will result in longer AS build times and higher memory consumption but can potentially help reducing the traversal time because of more optimal AABB sizes inside the BVH.
It’s scene content dependent. You need to experiment with it.

See the comment inside the optixMotionGeometry.cpp. Note that it’s not setting motion keys on the root IAS in the default code path (motion is enabled only if motionOptions.numKeys > 1):

    // we choose FAST_BUILD here as we need to rebuild every frame, no update or compaction needed
    state.ias_accel_options.buildFlags = OPTIX_BUILD_FLAG_PREFER_FAST_BUILD;
    // In this interactive sample, build times can govern render times.
    // Hence, we build a static IAS with faster build times despite slower traversal times.
#if 1
    state.ias_accel_options.motionOptions.numKeys = 1;
#else
    state.ias_accel_options.motionOptions.numKeys = 2;
    state.ias_accel_options.motionOptions.timeBegin = 0;
    state.ias_accel_options.motionOptions.timeEnd = 1;
#endif
    state.ias_accel_options.operation = OPTIX_BUILD_OPERATION_BUILD;

Another example doing that is intro_motion_blur example which is using two motion keys for one frame of the animation using linear and SRT motion matrices of the animated objects in the scene, but the root IAS doesn’t need motion steps at all to work.
https://github.com/NVIDIA/OptiX_Apps/blob/master/apps/intro_motion_blur/src/Application.cpp#L1813