4
$\begingroup$

I have a Optix Raycasting renderer which loads and renders VTK files. For a single static model this works fine.

But now my dataset consists of multiple timesteps which I want to display in a animated fashion.

Each couple of frames or seconds the displayed model has to be switched out with the next one. If possible I want to refrain from rebuilding the acceleration structure each time this happens.

So my question: Can I just load all models at once, place them in the global acceleration structure and then just switch all off except the one currently displayed. My hope is that this would be more efficient.

Edit 1: I have now build a variant in which I create optix::Acceleration and optix::Group for each of the timesteps separate and each time the active timestep changes I just

_context["top_object"]->set(mesh_group[timestep]);

But each this call takes nearly half a second. I think optix does quite some work in the background when I switch this object out. This delay is not acceptable for me as it makes the playback of my "animation" stutter.

Has anyone a idea how to do this more efficient?

$\endgroup$
3
  • $\begingroup$ I'm not familiar with the framework, but wouldn't it be more efficient to create an acceleration structure for each model? $\endgroup$
    – Rotem
    Commented May 7, 2016 at 12:39
  • $\begingroup$ Okay. Yes, but then I have to switch out which mesh is the currently active one... I think that would be doable... switching just works by setting a variable in the graphics memory I think. I would have to try if this influences perfomance in a big way. Thank you for your suggestion. $\endgroup$
    – Dragonseel
    Commented May 8, 2016 at 17:10
  • $\begingroup$ @Rotem I tried to just create everything before displaying, and then only switching it out... It turns out each time tell Optix to use another model this takes nearly half a second and my "animation" looks really unsmooth. $\endgroup$
    – Dragonseel
    Commented May 9, 2016 at 11:41

1 Answer 1

3
$\begingroup$

With help from the Nvidia Forum and two very helpful and friendly Nvidia employees I found the perfect solution.

In OptiX there is a so called selector node. This is a special scene-graph node that utilizes a user specified program to select which child a ray should traverse and which not.

#include <optix.h>

rtDeclareVariable(unsigned int, timestep, , );

RT_PROGRAM void animation_selector()
{
    rtIntersectChild(timestep);
}

This is a simple version of such a selection program. From the CPP-API side the current timestep will be set and can be used to make the animation. And then when the scene graph is traversed the program just says "Traverse only the child with index 'timestep'". This does not trigger a recompile or refit and therefore is nearly instant.

The selector node is simply created in following way:

optix::Selector selector = context_->createSelector();

std::string path_to_ptx = VRTPtxFinder::GetPtxPath("VistaRayTracing_generated_animation_selector.cu.ptx");

optix::Program selection_program = context_->createProgramFromPTXFile(path_to_ptx, "animation_selector");
selector["timestep"]->setUint(0u);
selector->setVisitProgram(selection_program);

for(auto group : groups)
{
  selector->addChild(group);
}

The only cost is one additional method call for each traversal and thereby also a slightly bigger stack which caused me some problems with a stack overflow so when using this, keep an eye on the stack size.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.