技术开发 频道

CUDA Volume Rendering[Part1:简介]

  【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

ray

  由觀測點(eye)往 volume 看,每一條「視線」,都根據某個固定的間距在 Volume 中取樣,然後依此累算出這條視線最後會呈現的顏色。實際上,每一條線會對應到最後呈現的圖上的一個點;所以最後要呈現的解析度要多高,就得做幾次這樣的運算。

  Slice base

slice

  根據和視線的垂直方向,把 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 列表如下:

mainmain 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 函式,進行計算。
displayglut 的 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_renderCUDA 的 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

0
相关文章