Start rays from each primitive in scene

Sorry to bother you again!

For my thermal tool I want to shoot rays from each triangle loaded in the scene. Is there an easy way I can access the geometry from inside the rg() program? As far as I know from the documentation, optixGetTriangleVertexData() only works in the hit programs.

So I guess, that I will have to write my own function which iterates over the triangles and passes the launch parameters to OptiX? Am I correct in this assumption?

Thanks for your help!


You should be able to call optixGetTriangleVertexData() from your raygen program. Was it not working? I think it just hasn’t been added to the matrix of device functions in the documentation because it’s new.


Yeah, I looked at the device functions table and assumed it wasn’t supported.
Thank you, I will try it out now!

Using OptiX 7 on the 441.87 driver in VS19.

I am starting from the optixMeshviewer example.

I used optixGetTriangleVertexData in the rg() and it at least returned me some coordinates.
Somehow always at least one of the entries seems to vary by a tiny margin. Is this expected behavior? Do I still need to transform the coordinates back to world space? From what I see the transform shouldn’t be the issue here.

To troubleshoot I copied my code into the ch() and let it print all three vertexes and the triangle it hit. If I understand correctly the returned values should not fluctuate between different threads? I am not (consciously) using any geometry transforms. I just load this gltf file into the scene.

The params.handle is the one from the default struct of the example.

float3 data[3];
if (optixGetPrimitiveIndex() == 1)
	 for (int i = 1;i < 4;i++){
	 printf("my triangle is %d, vertex %d is x %f, y %f, z %f \n",
         optixGetPrimitiveIndex(),i, data[i].x, data[i].y, data[i].z);

Are those some issues with single precision float accuracy or did I mess up the code?

Thank you for your help and have a nice weekend!

The vertex data will not change from call to call once it’s working correctly.

I suspect you probably just need to add the build flag OPTIX_BUILD_FLAG_ALLOW_RANDOM_VERTEX_ACCESS when building your acceleration structures.

Also your for loop is using 1-based indexing, it should be 0-based indexing.


If you used params.handle from the launch parameters used inside the optixMeshViewer example without changes to that application, the handle argument in optixGetTriangleVertexData(params.handle, …) will not work because that needs a GAS handle, but the optixMeshViewer sets an IAS handle as root traversable handle.

See optixMeshViewer.ccp line 214:

params.handle = scene.traversableHandle();

and Scene.h line 103:

SUTILAPI OptixTraversableHandle                    traversableHandle() const    { return m_ias_handle; }

Thanks to both of you for your answers.

How can I pass several flags to the builder? I tried several ways to include two flags but I keep getting an error in the optixAccelBuild function. I didn’t find anything on the forum or the documentation regarding this issue. Would be so kind to point me in the right direction? If I understood correctly the flags are not mutually exclusive?
Also: 1-based indexing, the old MATLAB curse. Thanks for pointing that out!

I am having trouble understand the implication of what you said in your post Detlef Roettger.

With the IAS handle from the example it seems to work (kind of?), so is it just a bad practice or am I just lucky and just didn’t crash for my geometry?
How would I work around that?
Do I have to pass the handles of the in the IAS contained GASes to optixGetTriangleVertexData?
Or do I have to flatten my Scene into one GAS? And also except from the primitive limit and I guess increased memory usage, is there a downside of only using one GAS?

Sorry for bothering you again, I’m looking forward to your replies!

Oh hey these flags are bitwise, so you can combine them using the bitwise OR operator like so:


Regarding your question, “Do I have to pass the handles of the in the IAS contained GASes to optixGetTriangleVertexData?”

You should pass the GAS handle to optixGetTriangleVertexData(), the GAS handle corresponding to the GAS where you built the triangles in question. The IAS handle won’t work and doesn’t contain any geometry data.

No need to flatten your scene or anything, you just need to use the same handle where you set the geometry when you want to get it back. The only downside to using a single GAS is you won’t get instancing, so you won’t be able move things around dynamically without rebuilding your GAS, and you won’t get to share or re-use duplicate meshes.


Thanks for your answer David!

I was able to pass the handle of the compacted GAS to optixGetTriangleVertexData() and now the coordinates don’t fluctuate anymore.

We will de doing thermal analysis on CubeSats in space, so there shouldn’t be any any movement in the scene, only the direction from which the rays start will be subject to change. So for us it seems tempting to stick to one single GAS.

If I have several primitives in different IASes and GASes and were to try to retrieve the optixGetTraingleVertexData() I would need to know beforehand which primitive is in which GAS to pass the correct handle to the function? Or am I misunderstanding something?

Okay I think the function I was looking for is optixGetGASTraversableHandle()

Have a nice weekend.