• 沒有找到結果。

Texture Coordinates:

(1, 0), (0, 1), (1, 1), (0, 0)

Setup for Parallel Calculation using Fragment Shader

h

w w

h

19

頂點資料設定為四個分別為畫面四角的頂點(如圖 14 左),兩個三角片佔滿 全畫面,並且左下角對應至貼圖的(0, 0)位置,右上角則為(1, 1),在此設計下的 頂點著色器,只要單純將頂點位置傳入著色器的

gl_Position

參數,並將貼圖座 標傳入片段著色器中,各斷片的貼圖座標即以內插處理。

當我們有w×h項資料要平行時,包含在視框緩存內的所有資料,如:深度 附加( depth attachment )、顏色附加( color attachment )以及視框緩存物件本身的大 小,都將設定為w×h (如圖 14 右),並在開始 OpenGL 的繪製流程( rendering

pipeline )相關函數之前,以

glViewPort

將繪製範圍設定為相符的(0, 0, w, h),由 於上述頂點資訊的設定,如此將可使斷片著色器的觸發頻率與所希望的平行工 作數相等;換句話說,以

glViewPort

控制平行工作的工作數,平行工作以斷片 著色器完成,因此主要的演算法將在斷片著色器中實作。

因為深度附加並沒有辦法自由寫入資訊,OpenGL 會在裡面自動寫入深度測 試用的深度資料,更由於頂點資訊的設計使其無深度資訊(深度資訊將全數為

0 ),因此通常將繪製緩存( render buffer )設定為深度附加,僅作為繪製時流程的 資料存放用,而不作資料取出。

而顏色附加將設定為針對儲存各演算所結果的貼圖,貼圖的參數設定則依 照平行化所需的參數設定,如:長寬與視框緩存相等(w×h)、儲存不同資訊用不 同資料型態(顏色和座標用四維浮點數、光照遮罩( illumination mask )用一維浮點 數)等。

20 Depth of this pixel: L.length

… (etc.) VPL v }

light ray L

21

圖16繪製 RSM 的視框資料

除了傳統作陰影映射所需的深度圖(A)以外,此圖例舉最少所需的 VPL 資訊,如 顏色(B)、位置(C)及所在平面的法向量(D)

4-3 容積體資料型態與採樣

在 OpenGL 4.0 後的版本可以以分層繪製( layered rendering )將資料繪製至

3D 的貼圖,但由於 4-1 提到的 WebGL 及 VR 的應用,捨棄分層繪製時必須使用 的幾何著色器( geometry shader )及密鋪著色器( tessellation shader ),依然使用頂 點著色器和斷片著色器,並繪製至 2D 貼圖材質。LPV 的容積體位置資訊應為

Attachment Texture Data in Framebuffer Object (A)

(B) (C) (D)

22 壓縮累加入其所屬的容積體。假設 VPL 的全域座標( global coordinate )為 (𝑥𝑣𝑝𝑙, 𝑦𝑣𝑝𝑙, 𝑧𝑣𝑝𝑙 ),則換算至其所屬的 LPV 座標為:

23

其中𝑣𝑜𝑙𝑢𝑚𝑒. 𝑙𝑒𝑛𝑔𝑡ℎ為容積體的邊長(容積體為正立方體);𝐴𝐴𝐵𝐵.

𝑙𝑜𝑤𝑒𝑟-𝑏𝑜𝑢𝑛𝑑為整個場景的軸向邊界盒( Axis Align Bounding Box )的最底頂點,意即此 軸向邊界盒中任一點的三軸座標值都將大於或等於𝐴𝐴𝐵𝐵. 𝑙𝑜𝑤𝑒𝑟𝑏𝑜𝑢𝑛𝑑的三軸座 標值。

接著將所有 VPL 的貢獻值,轉換為 SH 係數累加至各個所屬的 LPV 中就完 成了第一步的光照資訊植入。根據 [14],相較於 3-3 向量與 SH 係數轉換的積分 式,此時的資訊為離散的採樣資訊,因此每個 VPL 貢獻度還要再乘上一個權重 來標準化,某容積體內 SH 係數𝑐𝑙𝑚和 VPL 中的資料關係如下:

𝑐𝑙𝑚 = ∑ 𝑣𝑝𝑙. 𝑐𝑜𝑙𝑜𝑟×𝑦𝑙𝑚(𝑣𝑝𝑙. 𝑑𝑖𝑟)×𝑤

𝑣𝑝𝑙

, 𝑤 = 𝑟2

𝑅𝑆𝑀. 𝑤×𝑅𝑆𝑀. ℎ

𝑣𝑝𝑙. 𝑐𝑜𝑙𝑜𝑟表示 VPL 的間接照明顏色;𝑣𝑝𝑙. 𝑑𝑖𝑟表示 VPL 的輻射方向;𝑤為在

[14]中,基於 LPV 數量及 RSM 涵蓋範圍所得的權重。

將數值植入容積體中這個步驟將對於每一個 VPL 進行,在沒有原子運算

( atomic operation )的支援下,只能以迴圈進行採樣,但由於 GPU 進行分岔 ( branch )的效率較差,平行化完成各 VPL 貢獻值的 SH 轉換後,針對所屬容積 體的位置,並將數值累加進所屬容積體的部分直接在 CPU 端以迴圈完成,將各

LPV 累加結果儲存至陣列並轉換為 2D 貼圖。

24

4-4 傳遞的平行化

圖18 LPV 傳遞的邏輯和實作差異

依據 [14] [2]的描述,將貢獻資訊傳遞至相鄰容積的邏輯方法,是向某容積 體的上下左右前後傳遞,如圖 18 上,在第 1 次傳遞後要進行第 2 次時,角落四 個容積體將被同時寫入,此方法是為散佈( scattering )的邏輯,在較舊的 GPU 和 圖像函式庫中是不被允許的,且使用斷片著色器平行的方法,無法以多個工作 項目,寫入同一貼圖的同一像素;如要平行完成此步驟,則要採取相反的方 向,由相鄰四面的資訊向該容積體累加,如圖 18 下,是為蒐集( gathering )的邏 輯,如此可以避免平行化時,多個工作項目對同一個區塊進行寫入的狀況。圖 中的綠圓圈為每個平行工作項目處理的容積體。

又因為 OpenGL 無法對於同一材質貼圖進行採樣後寫回,如此我們使用了 兩份一樣結構的貼圖,分為前貼圖及後貼圖,前貼圖儲存傳遞前的貢獻度資 訊,用於採樣;後貼圖則用於寫入傳遞後結果。每個傳遞階段結束再將兩份貼

Propagate iterations 0 1 2

processing target Logic:

Implementation:

25

HTC Vive,因此根據 OpenVR 的官方範例,透過 OpenVR 將本 OpenGL 實作的 成果呈現至 VR 裝置相當容易使用。

使用 OpenVR 時,只要透過

VR_Init

即可啟動 VR 裝置,但如要更輕易地處 理 VR 裝置給予的資訊,省去處理訊號的形變( distortion )、裝置姿態預測或同步 問題,可使用

VRCompositor

物件,來更加輕易地取得 VR 的姿態資訊。

針對 VR 裝置姿態的轉換矩陣,VRCompositor物件提供主要的幾個轉換矩 陣:

26

1. 根據轉頭、抬頭及低頭,計算場景可視範圍的旋轉及位移的 矩陣,相當於處理頭與軀幹的位置及關係

2. 處理各個旋轉角度,視點位移的矩陣,相當於處理眼睛與頭 的位置及關係。由於在 VR 中呈現場景須呈現視差產生立體 感,這個矩陣左眼及右眼各提供一份。在 HTC Vive 上提供調 整左右眼差距的功能,調整後會影響此矩陣的數值

3. 場景的透視( perspective )投影矩陣。理論上兩眼的投影矩陣應 該要相同,但由於訊號形變的關係,兩眼的投影矩陣會有一 點點的調整,使得投影矩陣也有兩份。

然後就是透過 OpenGL 繪製場景,由於要處理視差的問題,必須要有兩份 貼圖儲存不同眼的繪製結果,其解析度將以

IVRSystem::GetRecommendedRend-erTargetSize

取得 VR 裝置的解析度,最後再將兩份貼圖以

VRCompositor::Sum-mit

上傳至 VR 裝置的兩眼顯示區域,即完成 VR 裝置的結果顯示傳遞。

27

相關文件