【IT168 文档】Volume Render 是 CUDA 2.0 Beta 版新加入的一個範例,主要是直接透過 3D Texture 來做 Volume 的 Ray marching。
而由於傳統的電腦圖學都是以多邊形的方式來建構、繪製 3D 場景;這點和呈現 Volume 所需要的技術是不同的!所以 Volume Rendering 沒辦法直接使用傳統的電腦圖學方法來呈現。
而一般來說,常見的 Volume Rendering 有兩種概念:第一種是將 Volume data 建立出多邊形的資料,然後再用這些資料還繪圖;第二種則是直接拿整個 Volume 資料去畫,這種方法一般叫做 Direct Volume Render。
在 Direct Volume Rendering 又有數種不同的技術,下面列舉常見的兩種:
Ray casting
由觀測點(eye)往 volume 看,每一條「視線」,都根據某個固定的間距在 Volume 中取樣,然後依此累算出這條視線最後會呈現的顏色。實際上,每一條線會對應到最後呈現的圖上的一個點;所以最後要呈現的解析度要多高,就得做幾次這樣的運算。
Slice base
根據和視線的垂直方向,把 Vloume data 重新取樣,產生出多張和視線垂直的 slice;接著再由後而前,依序把這些 Slice 用傳統的多邊形方法來繪製。
而在 CUDA 2.0 的 SDK 中所提供的 Volume Rendering 範例(專案名稱就是 volumeRender,檔案在 C:\Program Files\NVIDIA Corporation\NVIDIA CUDA SDK\projects\volumeRender),就是 ray casting 的方法;不過,他藉由 CUDA 這套 SDK,可以發揮 nVidia GPU 的大量平行化的好處,來做 GPU 的 ray casting。
程式的基本概念,是把 Volume 的資料讀到電腦的主記憶體後,當成 3D Texture 來 bind 到 device memory 中,然後再透過 CUDA kernel 來透過存取 3D texture,進行 ray casting 的計算。而運算的結果,會直接當成 OpenGL 的 Buffer Object,直接畫出來;如此也避免了必須要先把結果由 device memory 複製回 host memory,再送到 OpenGL render 的傳輸時間。
他的程式檔有兩個:
volumeRender.cu
主程式、資料讀取和 OpenGL 等相關的部分。
volumeRender_kernel.cu
實際做 ray casting 的 CUDA kernel。
在 volumeRender.cu 中的 function 列表如下:
main | main function。 |
loadRawFile | 用來讀取 Volume data 的函式。 在這個範例中,Volume 的資料是用 3D 的 RAW 檔來儲的。 |
initPixelBuffer | 建立 OpenGL 的 pixel buffer object,用來對應到 CUDA ray casting 儲存結果的記憶體空間。也直接拿來畫出結果。 |
cleanup | 清理資料用的。 |
iDivUp | 做除法的無條件進位,用來算 grid 大小用的。 |
initCuda | 起始化 CUDA 的資料。 主要是把讀進來的資料建立成 3D Texture,以及建立顏色對應用的 transfer function(包含陣列資料以及 1D texture)。 |
render | 把旋轉矩陣由 host memory 複製成 device 上的 constant 變數。然後呼叫 kernel 函式,進行計算。 |
display | glut 的 callback function,用來顯示用的,每次要更新畫面,都是執行這個函式。 他會計算物體的旋轉矩陣,然後再呼叫 render() 來做 ray casting 計算,最後再把儲存了結果的 pixel buffer object 畫出來。 |
reshape motion mouse keyboard | 這四個 function 是 glut 的 callback function。 reshape 是當視窗大小位置改變時會被執行到、motion 是滑鼠移動時會被呼叫的、mouse 是滑鼠按鈕會執行的函式、keyboard 則是鍵盤的。 |
而在 volumeRender_kernel.cu 中,則是:
intersectBox | 計算一條視線和 Volume 的 box 的交點,並傳回相交的最近點和最遠點。 |
mul | 計算矩陣乘上一個向量。 |
rgbaFloatToInt | 把 rgba 四項的 color,轉換成一個 int 來儲存。 |
d_render | CUDA 的 device kernel function。 為每一個像素,用 Ray casting 的方法來計算他的顏色。 |
intersectBox計算一條視線和 Volume 的 box 的交點,並傳回相交的最近點和最遠點。
mul計算矩陣乘上一個向量。
rgbaFloatToInt把 rgba 四項的 color,轉換成一個 int 來儲存。
d_renderCUDA 的 device kernel function。
為每一個像素,用 Ray casting 的方法來計算他的顏色。
本文来自:http://heresy.spaces.live.com/blog/cns%21E0070FB8ECF9015F%213597.entry