1.纹理映射体绘制
基于软件实现的光投影体绘制算法计算量很大,不利于实时渲染。因此,图形常用于体画使用纹理映射来加速。其主要原理是用硬件作为纹理装载到硬件缓存中,实现插值和图像合成操作,提高绘制效率。基于图形硬件图形硬件的三维纹理功能,主要利用硬件的三线过滤插值能力,通过渲染多个垂直于视线的面片来重建整个三维结构。每个面片都使用三维纹理来决定颜色和透明度。这种方法的效果本质上与光投影相同。最新的方法可以直接利用三维纹理在图形硬件上实现光投影算法。
二、二维纹理映射
由于硬件技术的早期限制,显卡只能支持二维纹理映射。其基本思路是将每个坐标轴方向的切片作为二维纹理保存到图形硬件缓冲中。在光投影中,选择一组垂直于当前视线方向的纹理图像,并在硬件中插入和合成操作,以实现身体绘制。 VTK中的vtkVolumeTextureMapper2D类可用于基于二维纹理映射的体画。
#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL2); VTK_MODULE_INIT(vtkRenderingVolumeOpenGL); VTK_MODULE_INIT(vtkRenderingFreeType); VTK_MODULE_INIT(vtkInteractionStyle); #include <vtkSmartPointer.h> #include <vtkStructuredPoints.h> #include <vtkStructuredPointsReader.h> #include <vtkVolumeTextureMapper2D.h> #include <vtkColorTransferFunction.h> #include <vtkPiecewiseFunction.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkVolumeProperty.h> #include <vtkVolumeRayCastIsosurfaceFunction.h> int main(int argc, char* argv[]) {
vtkSmartPointer<vtkStructuredPointsReader> reader = vtkSmartPointer<vtkStructuredPointsReader>::New();
reader->SetFileName("data/mummy.128.vtk");
reader->Update();
vtkSmartPointer<vtkVolumeTextureMapper2D> volumeMapper =
vtkSmartPointer<vtkVolumeTextureMapper2D>::New();
volumeMapper->SetInputData(reader->GetOutput());;
/*************************************************************************/
vtkSmartPointer<vtkVolumeProperty> volumeProperty =
vtkSmartPointer<vtkVolumeProperty>::New();
volumeProperty->SetInterpolationTypeToLinear();
volumeProperty->ShadeOn(); //打开或者关闭阴影测试
volumeProperty->SetAmbient(0.4);
volumeProperty->SetDiffuse(0.6); //漫反射
volumeProperty->SetSpecular(0.2); //镜面反射
//设置不透明度
vtkSmartPointer<vtkPiecewiseFunction> compositeOpacity =
vtkSmartPointer<vtkPiecewiseFunction>::New();
compositeOpacity->AddPoint(70, 0.00);
compositeOpacity->AddPoint(90, 0.40);
compositeOpacity->AddPoint(180, 0.60);
volumeProperty->SetScalarOpacity(compositeOpacity); //设置不透明度传输函数
//设置颜色属性
vtkSmartPointer<vtkColorTransferFunction> color =
vtkSmartPointer<vtkColorTransferFunction>::New();
color->AddRGBPoint(0.000, 0.00, 0.00, 0.00);
color->AddRGBPoint(64.00, 1.00, 0.52, 0.30);
color->AddRGBPoint(190.0, 1.00, 1.00, 1.00);
color->AddRGBPoint(220.0, 0.20, 0.20, 0.20);
volumeProperty->SetColor(color);
/********************************************************************************/
vtkSmartPointer<vtkVolume> volume =
vtkSmartPointer<vtkVolume>::New();
volume->SetMapper(volumeMapper);
volume->SetProperty(volumeProperty);
vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();
ren->SetBackground(0, 1, 0);
ren->AddVolume(volume);
vtkSmartPointer<vtkRenderWindow> rw = vtkSmartPointer<vtkRenderWindow>::New();
rw->AddRenderer(ren);
rw->SetSize(480, 480);
rw->Render();
rw->SetWindowName("VolumeRendering by Texture2D");
vtkSmartPointer<vtkRenderWindowInteractor> rwi =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
rwi->SetRenderWindow(rw);
ren->ResetCamera();
rw->Render();
rwi->Start();
return 0;
}
通过对比2D纹理体绘制程序与光线投影法绘制程序,会发现两者基本一样的,仅仅是vtkVolumeMapper不同。这充分说明了VTK体渲染管线的易用性与通用性。当从一种体绘制方法换到另一种时,只需要更换相应的vtkVolumeMapper即可。
3.vtkVolumeTexture2D类说明
vtkVolumeTexture2D类有两个重要的函数: SetTargetTextureSize(int_arg1,int _arg2);该函数用于设置纹理图像的大小默认为512*512.其大小必须为2的幂指数。 SetMaximumNumberOfPlanes(int _arg);该函数用于设置纹理映射的平面数目。当视线垂直方向上的像素数目大于该值时,平面会自动跳跃进行合理的映射。 基于vtkVolumeTexture2D类的二维纹理映射体绘制仅支持合成方式生成渲染图像。
4.与光线投影体绘制算法对比
基于二维纹理映射的体绘制速度要优于光线投影体绘制。 但是vtkVolumeTexture2D仅支持Alpha合成技术,并且切片上使用实现纹理映射,为切片之间不进行任何处理。因此,该方法的体绘制渲染效果是低于光线投影算法的。该方法需要在三个方向上保存相应的纹理图像堆栈,占用内存也比较大。在渲染的过程中会根据视线方向选择当前最垂直的一组纹理,因此在进行两组纹理切换时,会导致渲染质量的下降。