Simple C Triangle Mesh Raytracing

Hi,

It feels like I am running in a dead end here…

I want to write a C raytracer to evaluate the performance benefit of all the Space Partitioning algorithms in Optix against our current ones so we might switch to Optix.

But the C samples in die SDK 4.0.0, 3.9.1 and 3.7.0 are written in C++ only SDK 3.7.1 has sample5
which is actually C.

So after reading the Quickstart_Guide and several Programming Guides I started to examine all the different SDK Samples.

What I got now is a simple Optix Programm that fills a buffer with a certain color and writes it to a ppm. So far so good.

Now I am looking for a simple Triangle Mesh Example.

Since I have a lot of questions which are not answered by the MeshViewer example.

I found an OptixMesh which has a function called ‘translateMeshToOptiX’ in which the buffers for optix are set but this is C++ again.

So am I assuming correct that even for a triangle Mesh I need to specify a Bounds and Intersection Program like in ‘/cuda_compile_ptx_generated_triangle_mesh.cu.ptx’ ?

If so where does ‘intersect_triangle’ from ‘triangle_mesh.cu’ come from ?

Also I found a ‘primeSimple’ example which appears to do the shading on the CPU would it be possible to get the shading done on the GPU via callable Programs to allow recursion easily ?

So all in all a lot off questions, Regards ~xoryouyou

>>But the C samples in die SDK 4.0.0, 3.9.1 and 3.9.1 are written in C++ only SDK 3.7.1 has sample5 which is actually C.<<

That is not true. Up to OptiX 3.9.1 all samples from sample1 to sample5 are using the OptiX C-API in *.c files.

The OptiX C-API also has not changed at all. Only new functions got added over time.
If you have code which runs under OptiX 3.x using the C-API there should be no problem to get this to compile and run with OptiX 4.0.1 as well.

The C++ wrappers are implemented inside the OptiX SDK 4.0.1\include\optixu\optixpp_namespace.h header.
The naming scheme is simply the “rt” and “object” name removed and the rest is the name of the function implemented as member function in the respective C++ object class.
Which C-API gets wrapped by which C++ wrapper function is described inside the documentation comments in optixpp_namespace.h.

If you do not know where code comes from in any of the OptiX examples, the best tool to find out is “Find in Files” in your editor of choice over all .h;.cpp;*.c files inside the OptiX SDK.
In this case you’ll find the intersect_triangle function inside OptiX SDK 4.0.1\include\optixu\optixu_math_namespace.h.

The OptiX SDK contains two APIs, the high-level ray casting API OptiX and the low-level ray intersection API OptiX Prime.
In OptiX 4.0.1 the examples are named more clearly to make that distinction.

With OptiX Prime you setup a (big) number of rays in a buffer, let them trace and intersect with your triangle model, possibly instanced, and get a hit information back in a buffer of hit results of the same dimension as the input. Then you can do with the results whatever you like, for example shading in a CUDA kernel or on the CPU, setup a new batch of rays and repeat.

With the high-level OptiX API you have access to a complex scene hierarchy, programmable domains for raygeneration, miss, exception, intersection, bounding box, closest hit, any hit, and visit programs. Means it supports any primitive type you can write intersection routines for, not only triangles, and handles recursions, and ray continuation with any hit tests. It’s an API targeted “to the algorithm” with a simple single ray programming model.

My recommendations how to learn the OptiX API are here: https://devtalk.nvidia.com/default/topic/915251/?comment=4801716

Ok I See the samples are using the C-API but are still written in C++

I am using the Optix 4.0.0 SDK and there the sample which shows the C/C++ difference from the ‘NVIDIA-OptiX-SDK-samples.html’ is called ‘optixSphere’ or ‘optixSpherePP’.

And in ‘optixSphere’ are only .cpp files which confused me, so it’s showing how to use the C api from CPP.
Thats my wrong there.

Thanks for clearing up how the wrapper works.

I guess i’ll go and look for a OptixPrime solution where I throw a bunch of rays and recurse further if needed with only selected rays.

But still i can’t find the ‘intersect_triangle’ function even with a recursive search:

NVIDIA-OptiX-SDK-4.0.0-linux64/SDK» grep -r "intersect_triangle"
optixPrimitiveIndexOffsets/triangle_mesh.cu:  if( intersect_triangle( ray, p0, p1, p2, n, t, beta, gamma ) ) {
cuda/triangle_mesh.cu:  if( intersect_triangle( ray, p0, p1, p2, n, t, beta, gamma ) ) {

Not sure what your problem is there. I’m not using Linux.
It should be inside the header include\optixu\optixu_math_namespace.h in all OptiX versions.

I’d recommend to upgrade to OptiX 4.0.1 if you want to use OptiX 4.x.

No OS problem … seems just i searched in the ‘SDK’ folder and not in the above ‘include’.

So thanks for the hint.

But while we are at it, is there a best practice to call multiple rtpQuery executes one after another.

Since I would like to stay on the GPU and not switch context from the rtp Query to building new rays /shading on the CPU.

Just work through the OptiX Prime samples one by one.
The more advanced multi-buffering one shows how to trace asynchronously with multiple buffers in flight.
Enhancing that to shoot multiple wavefronts of rays should be able to achieve the best intersection performance.

The primeKernels.cu files in the OptiX Prime examples already contain some CUDA kernels to generate the primary rays. You could add your CUDA device functions for other operations there as well and keep things on the GPU.

I’m not really using OptiX Prime myself. I use OptiX because I have custom geometric primitive intersections in my renderers which also run on the NVIDIA VCA machines.

Ahh ok I just need the plain old ray/tri intersection.

I’ll check out the example especially since I don’t need the whole optix material / transform graph.

Thanks a lot for the answers.