Volume 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
|
---|---|
由觀測點(eye)往 volume 看,每一條「視線」,都根據某個固定的間距在 Volume 中取樣,然後依此累算出這條視線最後會呈現的顏色。 實際上,每一條線會對應到最後呈現的圖上的一個點;所以最後要呈現的解析度要多高,就得做幾次這樣的運算。 |
根據和視線的垂直方向,把 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]》。
[…] Ray Tracing(參考)…這次有可能顛覆整個 Computer graphics […]
讚讚
打扰您了,毕竟这是8年前的大作了~
在下试图运行CUDA7.5给的VolumeRender例程,显示出来的一直是全白窗口,把d_render的输出d_output改成全0也依然如故,不知从何下手了。
您是否遇到过这个问题呢?
讚讚
抱歉,Heresy 沒碰 CUDA 很久了。
不過,個人會建議你先檢查一下:
1. 你的 OpenGL 相關程式是否可以正常運作?
2. 其他的 CUDA 範例是否可以正確執行?
讚讚
这么快得到回复非常感谢!
的确,我要检查OpenGL是否有问题。
讚讚
[…] 的函式,可以針對特定的攝影機位置,使用 ray casting 的方法(很久以前的說明),來產生一組針對這個視角的 point cloud […]
讚讚
[…] 2.0 Beta 時並沒有很齊全,現在應該是把這些都補上了~不過像是範例程式 volumeRender […]
讚讚
[…] Pingback: CUDA Volume Rendering [Part.1 簡介] « Heresy's Space […]
讚讚
[…] part.1 大概介紹了 volume rendering 的概念,也大概列了一下裡面的 function。而 part.2 […]
讚讚
[…] part.1 […]
讚讚