The optixTransformNormalFromObjectToWorldSpace
helper function is one of the general purpose functions to handle any transform list size OptiX supports (see the Limits chapter inside the OptiX Programing Guide on the maximum traversable depth, it’s 31 today).
These helpers build the effective transform matrices by iterating over the transform list with
optixGetTransformListSize
and optixGetTransformListHandle(index)
and concatenate the respective transform types in the right order for transforms and their inverse. (This gets a little involved with motion transforms.)
The code doing that is inside the optix_device_impl.h
and optix_device_impl_transformations.h
headers.
So, my understanding is that there’s no equivalent of optixTransformNormalFromObjectToWorldSpace for “outgoing” hit objects?
Yes, since these are not using the optixGetHitObject
variants (optixGetHitObjectTransformListSize
and optixGetHitOjectTransformListHandle(index)
), they are apparently not working on hit objects.
If you’re only using an IAS->GAS structure, the transform list is exactly one entry and it’s an instance transform type! That simplifies the transformation handling a lot.
Getting the transform of a hit primitive then can use the hardcoded index 0 in optixGetTransformListHandle(0)
like here:
https://github.com/NVIDIA/OptiX_Apps/blob/master/apps/MDL_renderer/shaders/hit.cu#L118
and you know exactly that it’s an instance transform handle type, so getting the matrix can use optixGetInstanceTransformFromHandle
without checking the type. (Look at what other “TransformFromHandle” device functions exist.) and then use the respective transform functions:
https://github.com/NVIDIA/OptiX_Apps/blob/master/apps/MDL_renderer/shaders/transform.h
which are effectively the same operations as inside the point, vector, normal transform functions at the end of the OptiX SDK 8.0.0\include\internal\optix_device_impl_transformations.h
header, just with different arguments.
I use these because I want to get the transformation matrices only exactly once and use them in multiple transform calls which the helper functions don’t do. (The compiler hopefully optimizes that away.)
However, if I use optixTraverse, then I need to deal with the concept of incoming and outgoing hit objects.
Could you please explain what you’re implementing by using optixTraverse
and in what program domains you’re calling it?
After optixTraverse
returns there exists an “outgoing” hit/miss record, so if you’re using that to implement Shader Execution Reordering (SER) by calling optixTraverse, optixReorder, optixInvoke inside the ray generation program, there is no need to call any of the optixHitObject
functions at all.
Looks like this: https://github.com/NVIDIA/OptiX_Apps/blob/master/apps/MDL_renderer/shaders/raygeneration.cu#L183
or like inside the OptiX SDK optixPathTracer example which also shows how to use optixTraverse for shadow rays.
If you’re replacing the hit records with the optixMakeHitObject
functions, you would have retrieved data from some hit object with the optixGetHitObject
functions or the the current transform list before from which you would fill into your new hit object.
For the transforms you would need to provide the transform list size and an array of the transform handles inside the optixMakeHitObject transforms
and numTransforms
arguments.
https://raytracing-docs.nvidia.com/optix8/guide/index.html#shader_execution_reordering#hit-objects
You get the transform list size and handles from the incoming hit hit object with optixHitObjectGetTransformListSize
and optixHitObjectGetTransformListHandle(index)
.
In the case of an IAS->GAS graph, that would be numTransforms = 1 and only one transform handle (for the OptixInstance matrix) in that array.
So if you want to use optixTraverse and hit-objects manually, you would need to implement the transformation routines on that following my simple transform.h
version for the IAS->GAS case or the port the more complete helper functions inside optix_device_impl_transformations.h
to use hit object functions to retrieve that data.
Again, I’m not sure what your trying to implement and in what program domain.
Do you have a version of the algorithm which works with optixTrace calls?
Some code about what you’re planning would be helpful.