当多个对象(Xrays / Image3D)共享同一个Z平面时,我正在寻找一种控制不透明对象渲染顺序的方法。我一直在考虑在自定义的OpaquePass中重新排序PropArray,但我很好奇其他人是否有更清洁的程序。不幸的是,尽管使用SetDisplayLocationToForeground/BackGround()
方法,但使用Image2D并不是一种选择。
除了使用自定义OpaquePass注入我们自己的渲染代码之外,他们更清洁吗?该软件的用户将能够通过bringToFront / Back控件更改xrays的渲染顺序。
我已经能够在WebGL和Three.js中成功测试这种行为,它暴露了对渲染顺序的控制。 例如:
注意:我使用Python(2.7.5)和Python Vtk:5.10.1
答案 0 :(得分:1)
经过一个月的开发和故障排除后,我已经解决了!
以下是我如何解决VTK中的渲染深度问题。
注意:这将仅解决具有相同z深度的对象的渲染深度。尽管具有渲染深度,但前面或后面的对象将正常绘制。
逻辑
我们将在vtkRenderer的viewProps对象中编辑绘制顺序。渲染深度为null的所有vtkObject将首先绘制,然后是渲染深度的降序。
示例:强>
未分类的渲染深度
viewProps = [NULL,3,NULL,1,2,4,NULL]
排序渲染深度
viewProps = [NULL,NULL,NULL,4,3,2,1]
实施
向vtkObject添加一个名为" renderDepth"使用Get / Set方法。在vtkObject创建集renderDepth = NULL;
在vtkRenderer中创建一个方法(我将调用我的RenderDepthSort)。
递归调用viewProp对象树,然后简单冒泡排序,以交换任何具有渲染深度的项目。
vtkRenderer::RenderDepthSort(vtkPropCollection * propArray){
propArray->InitTraversal();
for(int i=0; i < propArray->GetNumberOfItems(); i++){
vtkProp * prop = propArray->GetNextProp();
if(prop->IsA("vtkAssembly")){
vtkAssembly * ptr = static_cast<vtkAssembly *>(prop);
if(ptr->GetParts()->GetNumberOfItems() > 0)
this->RenderDepthSort(ptr->GetParts());
}
}
bool isUnsorted = true;
while(isUnsorted){
isUnsorted = false;
propArray->InitTraversal();
for(int i=0; i < propArray->GetNumberOfItems()-1; i++){
vtkProp * propA = propArray->GetNextProp();
vtkProp * propB = static_cast<vtkProp *>(propArray->GetItemAsObject(i+1));
if(propA->GetRenderDepth() == NULL || propB->GetRenderDepth() == NULL){
if(propA->GetRenderDepth() != NULL && propB->GetRenderDepth() == NULL){
propArray->ReplaceItem(i, propB);
propArray->ReplaceItem(i+1, propA);
isUnsorted = true;
}
}else if(propA->GetRenderDepth() < propB->GetRenderDepth()){
propArray->ReplaceItem(i, propB);
propArray->ReplaceItem(i+1, propA);
isUnsorted = true;
}
} //end for loop
} // end while
}//end renderDepthSort Method
如果你像我们一样抽象出你的vtk实现,并且你没有完全控制你的vtkViewProps,那么就实现另一种方法来解决渲染深度并将它们传播到树上。
void vtkRenderer::InitSolveRenderDepths(vtkPropCollection * propArray){
int depth = NULL;
int numDepths = 0;
propArray->InitTraversal();
for(int i=0; i < propArray->GetNumberOfItems(); i++){
vtkProp * prop = propArray->GetNextProp();
if(prop->IsA("vtkAssembly")){
this->SolveRenderDepths(prop);
int temp = prop->GetRenderDepth();
if(temp != NULL){
if(temp < depth || depth == NULL){
depth = temp;
}
numDepths++;
}
}
}
}
<强>最后强>
再创建一个名为UpdateDrawOrder()的方法
void vtkRenderer::UpdateDrawOrder(){
vtkPropCollection * props = this->GetViewProps();
this->InitSolveRenderDepths(props);
this->RenderDepthSort(props);
}
将其设置为在vtkRenderer :: Render()或vtkRenderer对象中调用UpdateDrawOrder。
Z End!