我有一个Optix渲染器,它加载和呈现VTK文件。对于单个静态模型,这很好。
但是现在我的数据集由多个时间步骤组成,我想以动画的方式显示这些步骤。
每隔几个帧或每秒钟显示的模型必须与下一个切换。如果可能的话,我想避免每次都重建加速结构。
所以我的问题是:我能不能一次加载所有的模型,把它们放在全局加速结构中,然后关掉,除了当前显示的一个。我希望这样做会更有效率。
编辑1:我现在已经构建了一个变体,在这个变体中,我为每个时间步骤创建了optix::加速度和optix::Group,每次活动时间步骤更改时,我只是
_context["top_object"]->set(mesh_group[timestep]);但每次通话都需要近半秒的时间。我认为optix在切换这个对象时在后台做了相当多的工作。这个延迟对我来说是不可接受的,因为它会让我的“动画”口吃回放。
有没有人知道如何更有效率地做这件事?
发布于 2016-05-13 11:34:19
在Nvidia论坛和两位非常乐于助人和友好的Nvidia员工的帮助下,我找到了完美的解决方案。
在OptiX中有一个所谓的选择器节点。这是一个特殊的场景图节点,它利用用户指定的程序来选择射线应该遍历的子节点和不遍历的子程序。
#include <optix.h>
rtDeclareVariable(unsigned int, timestep, , );
RT_PROGRAM void animation_selector()
{
rtIntersectChild(timestep);
}这是这样一个选择程序的简单版本。从CPP方面,当前的时间步骤将被设置,并可以用来制作动画。然后,当场景图被遍历时,程序只会说“只遍历索引为‘timestep’的子程序”。这不会触发重新编译或重新修改,因此几乎是即时的。
选择器节点的创建方式如下:
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);
}唯一的代价是每次遍历都需要一个额外的方法调用,从而产生一个稍微大一点的堆栈,这给堆栈溢出带来了一些问题,所以在使用该方法时,请注意堆栈大小。
https://computergraphics.stackexchange.com/questions/2409
复制相似问题