1.紋理映射體繪製
基於軟件實現的光線投影體繪製算法計算量非常大,不利於進行實時渲染。因此,目前體繪製經常使用圖形硬件利用紋理映射來加速。
其主要原理是將三維體數據作爲紋理裝載入硬件緩存中,利用硬件來實現插值以及圖像合成操作,以提高繪製效率。
基於圖形硬件三維紋理功能的體繪製技術,主要是利用硬件的三線性過濾插值能力,通過渲染多個與視線垂直的面片來重建整個三維結構。每個面片利用三維紋理來決定顏色和透明度。這種方法得到的效果從本質上講與光線投影的效果相同。最新的方法可以直接利用三維紋理在圖形硬件上實現光線投影的算法。
2.二維紋理映射
早期受到硬件技術的限制,顯卡只能支持二維紋理映射。其基本思路是將每個座標軸方向的切片作爲二維紋理保存到圖形硬件緩衝中,在光線投影時,選擇與當前視線方向垂直的一組紋理圖像,在硬件中進行插值和合成運算以實現體繪製。
VTK中的vtkVolumeTextureMapper2D類可用於實現基於二維紋理映射的體繪製方法。
具體代碼如下所示:#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL); 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("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合成技術,並且切片上使用雙線性插值實現紋理映射,爲切片之間不進行任何處理,因此,該方法的體繪製渲染效果是低於光線投影算法的。
此外該方法需要在三個方向上保存相應的紋理圖像堆棧,佔用內存也比較大。
還有一點需要注意的就是,該方法在渲染過程中會根據視線方向選擇當前最垂直(會是最優嗎?)的一組紋理,因此在進行兩組紋理切換時,會長生瑕疵,從而造成渲染質量的下降。