in my user geometry I need to keep track of all primitives (kind of basis functions / splats with finite support) which are hit along each ray in sorted order. So basically the ray should store a list of the currently intersected bounding boxes, which is updated whenever a new box is intersected or a previous box is left. Logically, I want to traverse the ray-box overlap intervals along the ray in sorted order and know in each interval which boxes are currently active in that interval. Each interval could return a successful surface intersection, terminating the sampling along the ray.
The API documentation states that "filter functions can be used to [...] collecting all hits along a ray". Might this be a possible approach? To first collect all intersections, then sort them. But what would be a good way to store the active list of boxes per ray? And where would the sorting and intersection computation happen?
Thanks in advance!
To add to Carsten's response:
- This paper (and sample code) should also be helpful too: http://jcgt.org/published/0004/04/04/
- If you're using an Embree User Defined Geometry (UDG), you will have to explicitly manage the calling of the intersection filter yourself, as the current intersection filter code only works for Embree's built-in types. In your intersection code, you'll have to call your intersection filter appropriately, based on what you're trying to do. By using the intersection filter functionality in general, you can safely do multi-hit with mixed Embree primitives and your own UDG primitives. The key is that if you stash hits locally, but don't tell Embree to stop doing intersections (by setting geomID in the ray), Embree will keep looking for intersections. Then depending on your hit structure data layout (SoA vs. AoS vs. regular scalar C++), it may be better to sort hit points as they come in, or wait to the end of ray traversal and sort them as a post-process (what the above paper investigated).
- Embree only cares about the beginning layout of the ray structure, so you can cast the ray to a ray type you define with extra information in it (such as a hit list). This section of the Embree documentation confirms you can do this: https://embree.github.io/api.html#extending-the-ray-structure
Thank you very much! This certainly helps!
One question remains though: I want to implement this within a user geometry in OSPRay, so I assume I can not easily modify the initial camera structure.
Update: Nevermind, just checked common/Ray.ih in OSPRay, which contains a userdata pointer after the Embree ray layout. I will further investigate this tomorrow.
If you're using OSPRay (I work on the project), you can either use the sample code we created for the JCGT papers or have a look at some code here on Github: https://github.com/jeffamstutz/module_multihit
That code is an OSPRay "module", which means that if you clone it into OSPRay's "modules/" directory, then code in that directory will be compiled as a part of your OSPRay build. That module specifies an OSRPay trianglemesh, which adds Embree intersection filters for getting all hits, and a multi-hit renderer, which colors pixels in various ways based on info we needed for the JCGT papers. NOTE: because it was written to support a paper, there's various methods all squashed on each other, controlled with some #define options....so it could be WAY simpler than it currently is.
Hope that helps!