Correct setup for motion blur in optix 7?

I’m looking at adding motion blur to my renderer, and I’m not sure I understand exactly what I’m supposed to do. I have a very simple test scene with a triangle with two motion keys. Currently I:

  1. Create the GAS for the triangle object with both keys of vertex data, and setting 2, 0 and 1 for the motion options numKeys, timBegin and timeEnd, respectively.
  2. All modules are compiled and linked with usesMotionBlur and overrideUsesMotionBlur set to true.
  3. My rays are fired with a rayTime generated as a uniform random [0,1)
  4. …?

When I render I just get a static triangle.

Looking at the optixSimpleMotionBlur example, it seems as though I should be setting a list of AABBs in the OptixBuildInputInstanceArray, but it also says in that example that the triangle geo AABB is being ignored. In the docs it says “Build inputs must specify primitive vertex buffers (for OptixBuildInputTriangleArray) and AABB buffers (for OptixBuildInputCustomPrimitiveArray and OptixBuildInputInstanceArray) for all motion keys.”

So,

a) if I only have triangles in my scene and a static IAS, do I still need to pass AABBs to the instance array build? if the IAS is static, should I be passing an AABB that is the union of the motion keys’ AABBs?

b) in what circumstances do I need multiple motion keys on my IAS? The motion traversables specify their own keys, and in the docs it says “Traversables linked together in a scene graph may have a different number of motion keys, for example: a static IAS (zero motion key) linked to a mixture of GAS’s with zero or multiple motion keys per GAS.” which makes it sound like the IAS doesn’t need to specify motion keys at all?

I’m a little confused.

Your GAS setup looks good. I would try to get things working in stages maybe:

  1. What happens when you intersect the GAS directly (no IAS)?
  2. once 1 is working, what happens when you add your GAS to a static IAS with a single large BBox over your GAS?

Your questions:
a) I believe you only need to pass in AABBs for a static IAS when using custom geom. For triangle geom, optix automatically calculates parent AABBs over the GAS motion path. Yes, the bbox for the IAS should cover the entire motion path of the underlying traversable (in this case GAS)
b) you can decouple motion keys in IAS and underlying traversables. The simplest example of this is a static IAS (zero motion keys) and a 2-key GAS below it. The bounding boxes of the IAS must be expanded to encapsulate the child GAS’s motion path. Similarly you could have 2 keys for the IAS and 3 keys for the GAS – the bboxes passed to the IAS just have to correctly cover the path of first and second halves of the motion path of the GAS.

To keep things slightly simple, I would recommend trying to constrain your renderer to always keep the same number of time-steps for all motion blurred geom and then have all IASs have either the same number of keys or be static. Some real world systems do this.

We are hoping to provide a source utility to aid with common motion blur setups in the near future since they can be a bit confusing.

Thanks Keith, that makes a lot more sense now.

Is there a performance reason to choosing whether to use a static IAS with enlarged AABBs or using multiple AABB keys?

Just to be clear, it sounds like I can mix and match any number of AABB keys with any number of child accel keys, just as long as at any given time the (possibly interpolated) AABB for the IAS completely encapsulates the interpolated AABB of the child?

As an aside, is there any overhead to always setting usesMotionBlur to true in the module compile options and then just using the overrrideUsesMotionBlur flag in the pipeline link options as a global motion blur on/off toggle? Are the modules compiled with usesMotionBlur off better optimized in some way?

I’ve found the issue in my code - I had an FFI bug meaning that I wasn’t setting the motion options correctly as I thought.

Thanks Keith, that makes a lot more sense now.
No problem.

Is there a performance reason to choosing whether to use a static IAS with enlarged AABBs or using multiple AABB keys?
In general a motion IAS will perform better. The static IAS with expanded bboxes is easier to implement. This is why I setup the optixSimpleMotionBlur like that – to keep it simple

Just to be clear, it sounds like I can mix and match any number of AABB keys with any number of child accel keys, just as long as at any given time the (possibly interpolated) AABB for the IAS completely encapsulates the interpolated AABB of the child?
Correct

As an aside, is there any overhead to always setting usesMotionBlur to true in the module compile options and then just using the overrrideUsesMotionBlur flag in the pipeline link options as a global motion blur on/off toggle? Are the modules compiled with usesMotionBlur off better optimized in some way?
Yes! This precludes use of the fastest traversal path which makes optimal use of the ray-traversal hardware. Only enable motion blur at the module level if you cant avoid it. Pro-tip – the global override is going to be deprecated soon … and might even be a no-op now :).

Just directly tracing against my GAS still results in no motion blur, so that narrows down where my issue might be.
not sure … maybe try to hack in a hardcoded version of optixSimpleMotionBlur’s triangle GAS and start from there?? Or vice versa – take the SDK sample and modify it to mimic what you are doing? Good luck

Good to know! Thanks! So assuming I want to have a global toggle for motion blur on/off, I’d need to either recompile all my modules when this changes (since all modules in a pipeline are required to have the same compilation options), or keep two sets of modules around to be linked depending on whether i want motion blur or not?

Also I did a not-quite-ninja edit to my last post which overlapped with yours - it’s all working correctly I just had a silly bug in setting the motion options.

Glad you got things working. Yes, you would need to have separate compilations for MB on/off for your modules.

I can also confirm that the pipeline override doesn’t appear to do anything. At least for turning motion blur off when it’s enabled at the module level.

Is this also valid for a mixed scene, where custom geometry and in-built triangles are used side-by-side within one static IAS ?
So can the AABBs for the in-built triangle instances then remain undefined ?

the question is related to OptiX 7.0.0 SDK. in the source code there in the simple motion blur sample:
“NOTE: the bbox for the triangle geom is being ignored. Should it be???”
is this still valid?

Great News !

Update:

I tried out to use undefined AABBs

OptixAabb aabbs[1] = {};

in a modified simpleMotionBlur sample:

  • one IAS
  • with one GAS using in-built triangles
  • one motion blur transform between them IAS->MT->GAS

It turns out, that the undefined asbb array simply does not produce any output (simply nothing is visible during the app runs).
But when the aabbs are defined anything works ok (motion blur triangle is visible).

If those AABBs would be not required, then

instance_input.instanceArray.aabbs = NULL;
instance_input.instanceArray.numAabbs = 0;

should work also; but that gives an exception, so obviously AABBs seem to be required also for in-built triangles.
Or is this another use case than you described?

AABBs are required in your above example because there is a motion-transform between the GAS and IAS. The IAS cannot introspect through the motion transform to build its own BBoxes. Notice that in the simple motion blur SDK sample, the triangle GAS is directly attached to the IAS.

1 Like

@Keith_Morley Thank you for the clarification.