I’m building my UI bar with AntTweakBar for GLUT and it works good as I update values like FOV and call update camera and it updates stuff spontaneously. Now lets say I have a cornell box with a Sphere in the middle of it which I want to change the material as per my choice from the UI. I have Lambertian and Purely Reflective materials. I have two closest hit programs but the only difference between them is the calculation of outgoing ray direction.
Would you suggest using a rtVariable that sends a token and based on which deciding the new direction of ray traversal from a single closest hit program or updating the geometry instance with new material and loading geometry again and do shading from two closest hit programs [I tried the latter and its very inefficient in my opinion]? What is the best way of design to go with in terms of updating the renderer without any lag ??
Thanks in advance!
So I sent a simple rtVariable and decided which direction to choose based on the token sent from host and it updates spontaneously!! It updates from a single closest hit program…
>>Now lets say I have a cornell box with a Sphere in the middle of it which I want to change the material as per my choice from the UI. I have Lambertian and Purely Reflective materials. I have two closest hit programs but the only difference between them is the calculation of outgoing ray direction<<
In a brute force path tracer that would be alright, but in general that should not be the only difference between these two materials. You just described the sampling of the next ray direction, but a clever path tracer should also do next event estimation (direct lighting) for diffuse materials to reduce the time to quality a lot.
The most straight forward approach would be to simply exchange the Material node at that geometry instance and let OptiX recompile. Yes, that can take quite some time.
There is absolutley no need to reload any geometry or change the scene hierarchy except for that one Material node. If you get the impression you need to do that because you’re using some helper function in the OptiX example framework, try to implement your own scene hierarchy from scratch and understand what’s really necessary in a scene hierarchy.
Another approach would be to add multiple materials to the GeometryInstance and use some variable to switch between the material value inside the intersection program with rtReportIntersection(materialIndex) which allows to call one of multiple closest hit programs attached to different Material nodes at that GeometryInstance. For a general application with many possible materials this becomes unmanageable. It doesn’t need a recompile though.
The next approach only feasible for a few materials would be to have an Über-shader closest hit program for all BSDFs and use some ID to switch between them. That’s what you just described. This is actually not that bad for a restricted number of materials if you need instantaneous switching between them.
The next more flexible design would be to implement all BSDF sample and eval functions with bindless callable programs and call them depending on some material hierarchy description and parameters passed into the closest hit program. That’s exactly what I’m doing for my MDL capable path tracer: http://on-demand.gputechconf.com/gtc/2016/presentation/s6244-roettger-optix-mdl.pdf
Also needs a recompile when exchanging the materials in a scene, though the PTX kernel is smaller than if I had a closest hit program per material.