深度剥离depth peeling使用
渲染效果异常的原因:为了提高渲染效率,一般情况下默认使用的是alpha blending(alpha混合),即只渲染最近的一面;因而当半透明显示时就会有问题,此时可以使用depth peeling(深度剥离)
深度剥离通常通过深度测试来渲染场景,将最近的片段返回给眼睛。在第二次传递中,前一次传递的深度缓冲区被绑定到一个片段着色器。为了避免读-修改-写危险,源和目标深度缓冲区在每次传递时都会交换(ping pong)。如果片段深度小于或等于前一次测试的相关深度,那么这个片段将被丢弃,深度测试将返回下面的下一层。
还有一种dual dedpth peeling,区别在于从概念上讲,双深度剥离是指从前后和从前后两个方向进行深度剥离,每次从前面去一层,从后面去一层。
如果GPU有多个深度缓冲区,并且每个深度缓冲区与特定的颜色纹理相关联,那么这将很容易实现。有一个RGB纹理用于前后混合,一个RGBA纹理用于前后混合。中间的层将被剥离并在前后和前后混合纹理中混合。
深度剥离是非常准确但是比较耗时,因为是按一个一个像素渲染过去的,VTK还提供了另一种渲染方式,是按几何结构的质心渲染的:vtkDepthSortPolyData
This method consists in using two filters. First, append all the polygonal
geometry with vtkAppendPolyData. Then connect the output port of vtkAppendPolyData to the
input port of vtkDepthSortPolyData. Depth sorting is performed per centroid of geometry primitives,
not per pixel. For this reason it is not correct but it solves most of the ordering issues and gives a
result usually good enough.
-
使用深度剥离前提是显卡支持(仅英伟达),可用语句测试本机是否能使用这个方法
vtkSmartPointer<vtkRenderer> _vtkRenderer = vtkSmartPointer<vtkRenderer>::New(); vtkSmartPointer<vtkRenderWindow> _vtkRenderWindow = vtkSmartPointer<vtkRenderWindow>::New(); _vtkRenderWindow->AddRenderer(_vtkRenderer); //It performs per pixel sorting (better result) but it is really slow _vtkRenderWindow->SetAlphaBitPlanes(1); //Make sure multisampling is disabled : _vtkRenderWindow->SetMultiSamples(0); _vtkRenderer->SetUseDepthPeeling(1); //Set the depth peeling parameters (the maximum number of rendering passes and the occlusion ratio). _vtkRenderer->SetMaximumNumberOfPeels(100); _vtkRenderer->SetOcclusionRatio(0.1); _vtkRenderWindow->Render(); // you can check that the graphics card supported depth peeling: //_vtkRenderer->GetLastRenderingUsedDepthPeeling(); if (_vtkRenderer->GetLastRenderingUsedDepthPeeling()) { cout << "depth peeling was used" << endl; } else { cout << "depth peeling was not used (alpha blending instead)" << endl; }