CUDA Volume Rendering [Part.1 簡介]


volumeVolume Render 是 CUDA 2.0 Beta 版新加入的一個範例,主要是直接透過 3D Texture 來做 Volume 的 Ray marching。

關於 Volume Rendering 這項技術,可以先去參考維基百科的說明:「立體渲染」。不過還是大概提一下,Volume Rendering 實際上在醫學方面其實相當普遍;主要是一般的斷層掃描都是一張一張的平面影像,把這些平面影像按照順序堆疊起來,就會變成一個 3D 的影像資料(也就是所謂的 Volume data)。Volume Rendering 就是一種用來繪製這種 3D 影像資料的技術。(應用參考

而由於傳統的電腦圖學都是以多邊形的方式來建構、繪製 3D 場景;這點和呈現 Volume 所需要的技術是不同的!所以 Volume Rendering 沒辦法直接使用傳統的電腦圖學方法來呈現。

而一般來說,常見的 Volume Rendering 有兩種概念:第一種是將 Volume data 建立出多邊形的資料,然後再用這些資料還繪圖;第二種則是直接拿整個 Volume 資料去畫,這種方法一般叫做 Direct Volume Render。

在 Direct Volume Rendering 又有數種不同的技術,下面列舉常見的兩種:

Ray casting
Slice base
ray

由觀測點(eye)往 volume 看,每一條「視線」,都根據某個固定的間距在 Volume 中取樣,然後依此累算出這條視線最後會呈現的顏色。

實際上,每一條線會對應到最後呈現的圖上的一個點;所以最後要呈現的解析度要多高,就得做幾次這樣的運算。

slice

根據和視線的垂直方向,把 Vloume data 重新取樣,產生出多張和視線垂直的 slice;接著再由後而前,依序把這些 Slice 用傳統的多邊形方法來繪製。

上圖資料來源:Volume Rendering For Games

而在 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 這四個 function 是 glut 的 callback function。
reshape 是當視窗大小位置改變時會被執行到、motion 是滑鼠移動時會被呼叫的、mouse 是滑鼠按鈕會執行的函式、keyboard 則是鍵盤的。
這邊不多加解釋了。
motion
mouse
keyboard

而在 volumeRender_kernel.cu 中,則是:

intersectBox 計算一條視線和 Volume 的 box 的交點,並傳回相交的最近點和最遠點。
mul 計算矩陣乘上一個向量。
rgbaFloatToInt 把 rgba 四項的 color,轉換成一個 int 來儲存。
d_render CUDA 的 device kernel function。
為每一個像素,用 Ray casting 的方法來計算他的顏色。

而更進一部的內容,請參考下一篇《CUDA Volume Rendering [Part.2]》。


對「CUDA Volume Rendering [Part.1 簡介]」的想法

  1. 打扰您了,毕竟这是8年前的大作了~
    在下试图运行CUDA7.5给的VolumeRender例程,显示出来的一直是全白窗口,把d_render的输出d_output改成全0也依然如故,不知从何下手了。
    您是否遇到过这个问题呢?

    • 抱歉,Heresy 沒碰 CUDA 很久了。
      不過,個人會建議你先檢查一下:
      1. 你的 OpenGL 相關程式是否可以正常運作?
      2. 其他的 CUDA 範例是否可以正確執行?

發表留言

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料