Question about Instance Acceleartion Struction

In my work, I have been copying the primitive information each time in my approach.

That shouldn’t be necessary if you can instance one GAS multiple times using instancing.

What I wanted to inquire about is whether, when using OptixInstance, referencing the same GAS allows for only one model to be used in the actual GPU memory.

Exactly. You described that in your scene setup already when using the GAS0 multiple times under different instances.
That’s the beauty of raytracing. You can instance geometry a lot that way and have numbers of triangles on the screen which you wouldn’t be able to render in a reasonable time with a rasterizer without serious culling tricks.

Despite searching through existing tutorials, they seemed to imply the creation of new primitives for each instance.

I’m creating new GAS inside the intro examples to make them very simple. They could easily use the same GAS under different instances.
For example, the two createSphere() calls with the same arguments could also use just the first sphere two times:

My more elaborate examples build a unique key per GAS to be able to instance the geometry automatically.
E.g. search for keyGeometry in here:
The simply host scene graph I’m using takes care of the OptixInstance building later.
I’m assigning the material at the instance level, so the same geometry can be used with different materials.

The ASSIMP mesh loader routine can reuse whole models as well. It references the scene graph root node. Due to the flattening of the scene graph to an IAS->GAS, the individual geometry inside the model will result in separate OptixInstances. To instance the whole thing, there would need to be a multi-level render graph (IAS->IAS->GAS) and some changes to the material assignments.

Since the same set of rays is used, one Launch would call Trace three times:

Yes, for that you need only the single GAS and one IAS with two OptixInstances, one with the identity matrix and one with the transformation matrix placing the GAS at two different positions inside your scene.
Mind that you then need to transform your object space vertex attributes into the world space.
With a two level IAS->GAS that is very simple and I wrote my own specialized transform routines for that fastest scene layout.
Search the example code where these are used:

The intro_motion_blur example is using the general purpose transformation helper functions provided by the OptiX SDK. These are unnecessarily complex for the IAS->GAS structure which has only exactly one transform list entry.

Read the in that example repository and look at the rtigo10 and rtigo12 examples for the fastest and smallest SBT implementation.

The OptixInstance contains an sbtOffset field which allows to select a specific hit record start index inside the SBT.
The user defined instanceId field can be used to access arbitrary data per instance. That is how my later examples access the vertex attributes, indices, and material and light parameters.

That is, do the instances need to be configured to have the same SBT offset?

That depends on what you want your device programs to be per instance. If they should use the same hit record, just set the sbtOffset to zero. You only need to be able to access your vertex attributes and indices somehow,

The optixTrace “SBT” arguments allow to select different SBT records in addition to implement different ray types.
The effective SBT index is calculated with the formula in this OptiX Programming Chapter:

Some threads about render graphs and SBTs explaining various possible SBT layouts:

1 Like