第四章 OpenCL Ray Tracer
第二節 內核(Kernel)
內核是在 GPU 上執行的一段程式碼。這裡我們將本論文的光跡追蹤渲染器 的設計成四個內核,分別為光跡追蹤內核、陰影內核、環境遮蔽內核及著色內核。
而每一段內核的值型及順序皆由主機端控制。
光跡追蹤內核 (進行光線擊中測試)
陰影內核 (計算陰影效果)
環境遮蔽內核 (計算環境遮蔽效果)
著色內核 (計算每個像素的顏色)
15
壹、 光跡追蹤內核(Ray Tracing Kernel)
光跡追蹤內核的任務為產生主要追蹤光線,並計算在場景中的擊中點。一開 始,由主機端將相機座標與成像平面上像素的座標傳入內核,首先計算出主要追 蹤光線(primary ray)的方向。接著計算這個追蹤方向在場景中所擊中的面,並將這 個面的索引編號與擊中點座標儲存下來。最後再輸出一個大小與成像平面大小相 同的一維陣列結構(structure)-RayHit。如圖 6。這個一維陣列結構中則儲存每個 像素所屬的追蹤光線在接下來其他內核中計算用的必要資訊:追蹤光線方向、擊 中面的索引編號。
圖 6
為光跡追蹤內核輸出的一維陣列結構 RayHit。
次要光線(secondary ray)的光跡追蹤做法則是將 RayHit 回傳並重複執行光跡 追蹤內核,利用主要追蹤光線找到的擊中面編號計算出擊中點及擊中點向量,與 原來的追蹤線作計算得到次要追蹤線的方向,來執行次要光線的光跡追蹤。
而本論文主要著重在主要光線的光跡追蹤。
貳、 陰影內核(Shadow Kernel)
陰影內核的主要任務是次要光線的應用-陰影(Shadow)。
在本內核中,由主要光線追蹤內核輸出的結果 RayHit 將傳入陰影內核中計算,
typedef struct {
float ray[3];
//追蹤線向量int sufacenum;
//擊中面的索引編號} RayHit;
16
該內核會以主要光線的擊中點與光源的位置產生一條陰影追蹤線(Shadow ray),用 來測試此擊中點與光源之間是否有受到其他物體的遮擋,若有則此擊中點處於陰
參、 環境遮蔽內核(Ambient Occlusion Kernel)
環境遮蔽內核的主要任務為次要光線應用-環境遮蔽(Ambient Occlusion)。
由主要光線追蹤內核中得到的 RayHit 傳入環境遮蔽內核,該內核會以 RayHit 中的資訊計算出主要光線的擊中點的座標與法向量,並以此法向量方向做隨機取 樣來得到環境遮蔽追蹤線(Ambient occlusion ray)。接著在這條追蹤線的方向上搜 尋場景中是否有受到其他物體遮蔽。環境遮蔽內核的輸出為一個與成像平面大小 相同的一維陣列結構-Accessibility。如圖 8。其初值為 0,每一條環境遮蔽追蹤
typedef struct {
int shadow_value;
//陰影遮擋量} Shadow;
17
線搜索場景的結果,若有遮蔽則加 1,若無則不加任何值。接著將 Accessibility 輸出至著色內核中來計算環境遮蔽率。順便一提,與陰影內核相同,這裡也經由 重複執行環境遮蔽內核來累積環境遮蔽的取樣數,得以讓環境遮蔽的效果更加精 細。
圖 8
為環境遮蔽內核輸出的一維陣列結構 Accessibility。
肆、 著色內核(Shader Kernel) 乘積,平均以得到環境遮蔽率。最後將 Phong 打光模型中的環境光(Ambient)乘上 未遮蔽率來得到環境遮蔽的效果。
typedef struct {
int Accessibility_value;
//環境遮蔽量 } Accessibility;18