第二章 文獻探討
2.1 Global Illumination
全域照明是 3D 計算機圖學領域中為了使畫面更為逼真而考慮真實光線於 3D 場景中光照效果的總稱,全域照明除了考慮到直接光源的照明,更包含了如間接 照明、反射、折射、焦散等效果。此領域至今已經發展出許多方法能夠達到擬真 的畫質,如輻射度(radiosity)、路徑追蹤(path tracing)、光子映射…等。但由於模擬 真實光照情形都避免不了大量複雜的運算,使其效能一直未見起色,在全域照明 的實作中也分成了兩派:著重畫質的靜態渲染(off-line rendering)以及著重效能的 即時渲染(real-time rendering),前者多為電影、動畫所使用的技術,而後者則運用 在遊戲產業以及相關特效上。本研究中,我們將專注於以光子映射實作全域照明 效果,並盡可能地利用 GPU 平行化的能力提升其效能,然而,光靠光子映射的資 訊無法完整的捕捉到多種層次的照明效果如:鏡面反射、透明折射…等,因此,
這些效果需要藉重其他方法的輔助以實現,我們使用了光線追蹤法的幫助以逼近 這些效果。
2.1.1 Ray Tracing
光線追蹤演算法的概念是由攝影機所在的位置,朝投影平面發射光線,判斷 該條光線是否擊中場景,並藉由擊中點與光源之間的關係來決定畫面中每個像素 的顏色,在[Whitted 80]的研究中,追蹤了不只一層的光線,並將光線分為陰影、
折射以及反射三種性質,借此計算出每一層次所追蹤的光照貢獻。另外,藉由發 射陰影射線,從擊中點射向光源位置判斷是否與場景物體有交點,則能夠快速地 計算出該處是否被場景所遮蔽,因此能夠計算出陰影。光線追蹤演算法具有渲染
4
畫面的數學正確性,並且能夠直覺地進行計算,是一個十分有發展性的演算法,
而為了模擬更真實的光照情形,例如全域照明或是次表面散射,部份進階的光照 算法或特殊材質則會需要更多的光線來模擬。
2.2 Photon Mapping on GPGPU
Photon mapping [Jensen 01]是一個在 GPGPU 架構下能夠良好運行的演算法,
具有模擬出真實光照中部分效果的能力,例如:間接散射、範圍光源、焦散…等 等。更重要的是他具備了在各種等級的裝置中能夠收斂於正確結果的特性,使得 光子映射演算法十分適合 GPU 平行化的性質。
Photon mapping [Jensen 01]演算法分為幾個步驟,發射光子、追蹤光子以及彙 集光子,近年來的研究中,已經有一些例子將 photon mapping 實作應用於 CUDA 與 OpenGL shader 平台上以利用 GPU 的平行運算能力。為了方便後續討論,我們 將發射光子以及追蹤光子步驟直到產生光子映射圖(photon map)的階段,統稱為 photon emission,而彙集光子的貢獻部份則稱為 final gathering。
2.2.1 Photon Emission
Photon mapping[Jensen 01]演算法中,這一個步驟將計算光子的發射、追蹤與 紀錄,是形成光子映射資訊的主要運算,光子的發射與追蹤跟光線追蹤的方式大 同小異,差別在於由光源位置做為出發點發出射線,在找到場景交點時以俄羅斯 輪盤(Russian roulette)的方式,隨機地決定光子於場景中是否儲存於交點位置或是 繼續下一輪彈跳,並因應不同的材質修改追蹤的路徑,在我們的實作中,限制了 光子路徑的追蹤深度以減少延遲,並且只執行到累積一定的光子數量為止。
2.2.2 Final Gathering
最終彙集(final gathering) 由於必須計算所有鄰近光子對於物體的貢獻,因此
5
計算量十分龐大,加速此一步驟一直是光子映射演算法的主要研究議題,至今,
已發展出許多不同的方式進行加速。主要分為兩種做法,一個是 photon gathering,
針對每一個場景交點計算光子對其造成的貢獻,另一個是 photon splatting,對於 每一個光子計算所影響到的像素,兩者都發展出螢幕空間的方法能夠大幅地提升 效率。 Photon Mapping [Jensen 01]使用 distributed ray tracer 配合光照的層次不同,
利用光子映射資訊做出近似計算;Image Space Photon Mapping(ISPM) [McGuire 09]
利用 GPU 硬體的能力產生多張 bounce map 並使用 photon volume 加速光子彙集 的計算,達到了即時的效能;Efficient GPU Density Estimation [Mara 13]中討論了 許多種彙集光子的方法,包含在傳統 GPU 硬體以及 GPGPU 的加速方式,其中提 到了兩種在目前架構上最可行的方式:2.5D gathering 與 tiled gathering,前者利用 傳統 GPU 硬體以螢幕空間加上 Z-buffer 的資訊計算彙集光子的區域,後者利用 GPGPU 共享記憶體儲存並以螢幕空間區隔光子,節省檢查次數和記憶體頻寬,此 方法被我們認為在目前異質多核心平台架構最具有潛力以及可行性。
2.3 OpenCL Platform
OpenCL 全名為開放式計算語言(Open Computing Language),主要由 Khronos 所開發,具備了跨平台的特性,能夠利用裝置中的多個核心平行計算,
並且具有符合異質系統架構運算的能力,是現今許多廠商共同支持的多核心計算 標準。OpenCL 不僅僅在 CPU、GPU 上能夠運行,在平板電腦以及移動式裝置上 亦能夠良好的搭載。藉由他的多核心平行化能力提供了以任務為主(task-based)與 以資料為主(data-based)的平行化機制,使得複雜的計算得以平行化處理。
2.3.1 Execution Model
在 OpenCL 平台上,程式主要分為兩個部份:主機端(host)與裝置端 (device),主機端程式是屬於一般的應用程式,而裝置端則是執行裝置內核程式
6
(kernel program),一個主機端程式可以啟動多個內核程式進行不同的運算,並且 也具有同時在不同裝置下執行內核程式的能力,在異質系統架構中,由於不需要 頻繁地在主機端記憶體與裝置端記憶體之間傳遞資料,最被看好的即是此種多裝 置平行化運算的潛力。
OpenCL 的內核程式執行架構是屬於 Single Instruction Multiple Thread (SIMT) 的模式,同一個工作群組(work group)中的內核執行緒(kernel thread)將同時執行同 一行指令,因此,使用者能夠根據裝置具有的運算單元數量,自行調整內核程式 的工作群組大小,決定程式平行化的程度,藉此提升效能。
2.3.2 Memory Model
根據裝置端所使用到的不同架構,OpenCL 平台記憶體層次也分成全域記憶 體(global memory)、唯讀記憶體(constant memory)、共享記憶體(local memory)、私 有記憶體(private memory)四種層次。
全域記憶體是所有的內核執行緒都能夠存取的記憶體區塊,其容量最大但是
另外,OpenCL 提供了 image object 的形式以利用全域記憶體區塊,最大的優 點是能夠存取一整塊的區域,並提供快取功能,但必須透過特定 API 來支援,適 合存放存取頻繁的資料,但現今大多的裝置都能夠自動地支援全域記憶體的快取,
因此我們沒有用到這個特殊功能。
7 端,存放於全域記憶體,並等待回傳的畫面(frame buffer)以更新螢幕上的顯示畫 面。裝置端接收到資料並啟動渲染畫面的內核程式後,藉由 SIMT 的特性,就畫 面中的每一個像素產生追蹤光線,再計算出該執行緒所在的群組螢幕空間的區域 對應於場景中的範圍,並將於影響範圍內的光子資訊複製到共享記憶體區塊(此步 驟稱為 tile insertion),接著進行場景交點測試,若光線與場景得到交點,於顏色計
Host Device
Ray Generation
Intersection Test
Compute Color Contribution
Frame Accumulation
Tile Insertion
Setting kernel Arguments
Construct K-d tree Read Scene
Compute Photon Map