基於BRDF的無限海水渲染
前言
屏幕空間網格投影
Pierson-Moskowitz海浪譜
海水的BRDF模型
實現結果
參考文獻
前言
本文主要是關於實時海水渲染,海水幾何造型是基於Pierson-Moskowitz海浪譜的反演,然後疊加多個Gerstner擺動波來計算網格頂點的波浪偏移。光照方面則是基於Ross推出針對海水的B R D F BRDF B R D F (Bidirectional Reflectance Distribution Function,雙向反射分佈函數)物理模型。因代碼比較繁多,故均用僞代碼描述。源代碼暫不開放。本文如有錯誤,歡迎指出,非常感謝!
主要參考文獻爲《Real-time Realistic Ocean Lighting using Seamless Transitions from Geometry to BRDF》。
屏幕空間網格投影
1、大致算法
實現無限海面有多種方法,如LOD動態四叉樹算法、遠近平面平湊法以及屏幕空間網格投影法等。這裏我將採用屏幕空間網格投影法,這是一個非常巧妙的算法,表面上我們是在渲染無限大的海面,實際上我們只需處理屏幕大小的海面網格,整個算法的處理複雜度就僅與屏幕空間中的網格精細程度相關,與海面的規模無關。
算法大致步驟如下:
①在屏幕投影空間創建一個規則的平面網格Grid(座標範圍[ − 1 , 1 ] [-1,1] [ − 1 , 1 ] );
②將上一步的網格Grid投影到海平面上,即變換到世界空間,此時得到一個水平面;
③對網格Grid進行Displace,即計算每個網格點的波浪偏移量,加到對應的頂點上;
④最後將海面網格Grid投影回屏幕空間。
2、具體細節
①在屏幕投影空間創建網格 :
一個模型要顯示到屏幕上,需要經過世界變換 → \to → 視圖變換 → \to → 投影變換 → \to → 視口變換 。我們創建的網格直接在屏幕投影空間中,不需要經過世界變換、視圖變換以及投影變換,故網格的x x x 、y y y 座標範圍爲[ − 1 , 1 ] [-1,1] [ − 1 , 1 ] ,而z z z 的座標值爲0 0 0 ,此時該網格就已經在屏幕投影空間了。
值得注意的是,我們創建的網格要比[ − 1 , 1 ] × [ − 1 , 1 ] [-1,1]\times[-1,1] [ − 1 , 1 ] × [ − 1 , 1 ] 的範圍稍微大一些。因爲我們將網格投影到世界空間時,還要加上波浪的偏移量,這可能導致邊緣部分因爲發生了一些偏移而使得網格邊緣凸顯出來了,破壞了我們在渲染無限海面的假象。
②將屏幕網格投影到世界空間的水平面 :
首先求出以網格頂點爲起點、方向指向水平面的射線,然後求該射線與水平面的交點。對於世界空間的一點,經過視圖變換、投影變換我們有:
P p r o j = M p r o j ∗ M v i e w ∗ P w o r l d P_{proj}=M_{proj}*M_{view}*P_{world} P p r o j = M p r o j ∗ M v i e w ∗ P w o r l d (列主序矩陣的寫法) (1)
那麼現在反過來已知P p r o j P_{proj} P p r o j 求P w o r l d P_{world} P w o r l d ,則有:
P w o r l d = M v i e w − 1 ∗ M p r o j − 1 ∗ P p r o j P_{world}=M_{view}^{-1}*M_{proj}^{-1}*P_{proj} P w o r l d = M v i e w − 1 ∗ M p r o j − 1 ∗ P p r o j (2)
我們在屏幕空間創建的網格z座標爲0,即深度爲0,因此由(2)求得的P w o r l d P_{world} P w o r l d 是世界空間下射線的方向向量。射線的方程可表示爲:
p = p 0 + d i r ∗ t p=p_0+dir*t p = p 0 + d i r ∗ t (3)
其中p 0 p_0 p 0 爲射線起始點,d i r dir d i r 爲射線的單位方向向量。射線的任意一點都可以用方程(3)表示。它方程(3)寫成各個分量的表示形式就是:
p . x = p 0 . x + d i r . x ∗ t p.x=p_0.x+dir.x*t p . x = p 0 . x + d i r . x ∗ t
p . y = p 0 . y + d i r . y ∗ t p.y=p_0.y+dir.y*t p . y = p 0 . y + d i r . y ∗ t (4)
p . z = p 0 . z + d i r . z ∗ t p.z=p_0.z+dir.z*t p . z = p 0 . z + d i r . z ∗ t
而平面的方程爲:
A x + B y + C z + D = 0 Ax+By+Cz+D=0 A x + B y + C z + D = 0 (5)
水平面若垂直於y軸,則平面方程(5)可化簡爲:
y = E y=E y = E (6)
聯立(4)和(6)我們求得交點座標在射線方程(3)中的t t t 值:
p . y = p 0 . y + d i r . y ∗ t = E → t = E − p 0 . y d i r . y p.y=p_0.y+dir.y*t=E \to t=\frac{E-p_0.y}{dir.y} p . y = p 0 . y + d i r . y ∗ t = E → t = d i r . y E − p 0 . y (7)
因此我們根據t t t 可求得交點座標。
Pierson-Moskowitz海浪譜構建海浪
我們採用從 Pierson-Moskowitz海浪譜採樣的n個擺動波疊加構建海浪。
Pierson-Moskowitz頻譜給出了重力波的能量分佈,它是頻率的函數:
h ( ω ) ∞ S ( ω ) , S ( ω ) = α g 2 ω 5 e x p [ − β ( ω 0 ω ) 4 ] h(\omega)\infty \sqrt{S(\omega)}, S(\omega)=\frac{\alpha g^2}{\omega^5}exp[-\beta(\frac{\omega_0}{\omega})^4] h ( ω ) ∞ S ( ω ) , S ( ω ) = ω 5 α g 2 e x p [ − β ( ω ω 0 ) 4 ] (8)
其中h ( ω ) h(\omega) h ( ω ) 爲波幅,重力常數g = 9.81 m s − 2 g=9.81ms^{-2} g = 9 . 8 1 m s − 2 ,α = 8.1 × 1 0 − 3 \alpha=8.1\times10^{-3} α = 8 . 1 × 1 0 − 3 ,β = 0.74 \beta=0.74 β = 0 . 7 4 ,ω 0 = g / V 20 \omega_0=g/V_{20} ω 0 = g / V 2 0 ,V 20 V_{20} V 2 0 爲海面上20米處的風速,參數ω \omega ω 爲角頻率。此外,式中∞ \infty ∞ 表示成正比例的關係。
①Gerstner擺動波 :
海浪水面渲染中我們使用的基礎波形並不是正弦波或餘弦波,而是一種叫做Gerstner波的特殊波形,Gerstner波和正餘弦波的區別,如下所示。與紅色的正餘弦波相比,Gerstner波在兩側有收緊的趨勢,和真實的海面更加接近。
一個二維的Gerstner波定義如下:
p = [ x + h s i n ( ω t − k x ) , h c o s ( ω t − k x ) ] T p=[x+hsin(\omega t-kx),hcos(\omega t-kx)]^T p = [ x + h s i n ( ω t − k x ) , h c o s ( ω t − k x ) ] T (9)
其中,h h h 爲振幅,t t t 爲時間,k k k 爲波數,ω \omega ω 爲角頻率,x x x 爲靜止時的水平位置。可以看出二維的Gerstner波是圍繞靜止時的位置[ x , 0 ] T [x,0]^T [ x , 0 ] T 做圓周運動。對於深水波浪,有ω = g k \omega=\sqrt{gk} ω = g k 。
我們把它推廣到三維,則三維的Gerstner波爲:
p h a s e = ω t − k x x − k z z = ω t − ( k x , k z ) ⋅ ( x , z ) phase=\omega t-k_xx-k_zz=\omega t-(k_x,k_z)\cdot (x,z) p h a s e = ω t − k x x − k z z = ω t − ( k x , k z ) ⋅ ( x , z )
p = [ x + h c o s θ s i n ( p h a s e ) , h c o s ( p h a s e ) , z + h s i n θ s i n ( p h a s e ) ] T p=[x+hcos\theta sin(phase),hcos(phase),z+hsin\theta sin(phase)]^T p = [ x + h c o s θ s i n ( p h a s e ) , h c o s ( p h a s e ) , z + h s i n θ s i n ( p h a s e ) ] T (10)
三維的Gerstner波圍繞靜止時的位置[ x , 0 , z ] T [x,0,z]^T [ x , 0 , z ] T 做圓周運動。在這裏波數k k k 變成了一個向量,稱爲波矢量,k = ( k x , k z ) = ( 2 π λ c o s θ , 2 π λ s i n θ ) k=(k_x,k_z)=(\frac{2\pi}{\lambda}cos\theta,\frac{2\pi}{\lambda}sin\theta) k = ( k x , k z ) = ( λ 2 π c o s θ , λ 2 π s i n θ ) ,故波矢量大小表示波數(即2 π λ \frac{2\pi}{\lambda} λ 2 π ,其中λ \lambda λ 爲波長,θ \theta θ 爲波的方向角,即波傳播方向與x x x 軸的夾角),波矢量方向表示波的傳播方向。
在構建海浪波形時,我們將n個擺動波進行疊加,每個擺動波都有各自對應的振幅、波矢量、角頻率,即( h i , k i , ω i ) (h_i,k_i,\omega_i) ( h i , k i , ω i ) 。我們將從Pierson-Moskowitz頻譜採樣獲取擺動波的( h i , k i , ω i ) (h_i,k_i,\omega_i) ( h i , k i , ω i ) 。
②Pierson-Moskowitz海浪譜反演 :
由式(8)知,波幅與S ( ω ) S(\omega) S ( ω ) 成正比,
h ( ω ) ∞ S ( ω ) , S ( ω ) = α g 2 ω 5 e x p [ − β ( ω 0 ω ) 4 ] = 8.1 × 1 0 − 3 × 9.81 × 9.81 ω 5 e x p [ − 0.74 ( ω 0 ω ) 4 ] h(\omega)\infty\sqrt{S(\omega)},S(\omega)=\frac{\alpha g^2}{\omega^5}exp[-\beta(\frac{\omega_0}{\omega})^4]=\frac{8.1\times10^{-3}\times9.81\times9.81}{\omega^5}exp[-0.74(\frac{\omega_0}{\omega})^4] h ( ω ) ∞ S ( ω ) , S ( ω ) = ω 5 α g 2 e x p [ − β ( ω ω 0 ) 4 ] = ω 5 8 . 1 × 1 0 − 3 × 9 . 8 1 × 9 . 8 1 e x p [ − 0 . 7 4 ( ω ω 0 ) 4 ]
在實現中,我們取波幅如下:
h ( ω ) = A α g 2 ω 5 e x p [ − β ( ω 0 ω ) 4 ] ω Δ λ h(\omega)=A\sqrt{\frac{\alpha g^2}{\omega^5}exp[-\beta(\frac{\omega_0}{\omega})^4]\omega\Delta\lambda} h ( ω ) = A ω 5 α g 2 e x p [ − β ( ω ω 0 ) 4 ] ω Δ λ (11)
其中A A A 爲波幅峯值。爲了充分利用GPU的並行能力,我們在頂點着色器進行擺動波的疊加,每個擺動波的( h i , k i , ω i ) (h_i,k_i,\omega_i) ( h i , k i , ω i ) 由Pierson-Moskowitz海浪譜採樣獲得。爲此,我們生成n個隨機波浪 ( h i , k i , ω i ) (h_i,k_i,\omega_i) ( h i , k i , ω i ) ,將 ( h i , k i , ω i ) (h_i,k_i,\omega_i) ( h i , k i , ω i ) 存放至1 D 1D 1 D 紋理中,供頂點着色器進行採樣 。
爲了構建P-M海浪譜,我們採用波長劃分的方法,與此同時我們隨機獲取波的方向角。
值得注意的是,我們是按照波長從小到大的順序將每個波存放到1 D 1D 1 D 紋理中,這便於後面我們根據波長進行濾波操作。
③網格頂點位置 :
按照論文所述,我們不能直接將n n n 個擺動波疊加,而需要將波長λ \lambda λ 小於N m i n ∗ L N_{min}*L N m i n ∗ L 的擺動波過濾掉,其中N m i n N_{min} N m i n 是奈奎斯特下界,L L L 爲世界空間中網格單元的大小(原因不明)。
爲此,對於每個擺動波,我們乘上一個縮放係數w p , i w_{p,i} w p , i :
w p , i ( N m i n , N m a x , λ i / L ) = c l a m p ( λ i / L − N m i n N m a x − N m i n , 0 , 1 ) w_{p,i}(N_{min},N_{max},\lambda_i/L)=clamp(\frac{\lambda_i/L-N_{min}}{N_{max}-N_{min}},0,1) w p , i ( N m i n , N m a x , λ i / L ) = c l a m p ( N m a x − N m i n λ i / L − N m i n , 0 , 1 ) (12)
結合前面所述公式(10),每個網格頂點的最終位置如下:
P = ( X , Y , Z ) P=(X,Y,Z) P = ( X , Y , Z )
k i = ( k i , x , k i , z ) = 2 π λ i ( c o s θ i , s i n θ i ) k_i=(k_{i,x},k_{i,z})=\frac{2\pi}{\lambda_i}(cos\theta_i,sin\theta_i) k i = ( k i , x , k i , z ) = λ i 2 π ( c o s θ i , s i n θ i )
X = x + Σ 1 n w p , i h i c o s θ i s i n ( ω i t − k i ⋅ ( x , z ) ) X=x+\Sigma_1^nw_{p,i}h_icos\theta_isin(\omega_it-k_i\cdot(x,z)) X = x + Σ 1 n w p , i h i c o s θ i s i n ( ω i t − k i ⋅ ( x , z ) ) (13)
Y = y + Σ 1 n w p , i h i c o s ( ω i t − k i ⋅ ( x , z ) ) Y=y+\Sigma_1^nw_{p,i}h_icos(\omega_it-k_i\cdot(x,z)) Y = y + Σ 1 n w p , i h i c o s ( ω i t − k i ⋅ ( x , z ) )
Z = z + Σ 1 n w p , i h i s i n θ i s i n ( ω i t − k i ⋅ ( x , z ) ) Z=z+\Sigma_1^nw_{p,i}h_isin\theta_isin(\omega_it-k_i\cdot(x,z)) Z = z + Σ 1 n w p , i h i s i n θ i s i n ( ω i t − k i ⋅ ( x , z ) )
其中( x , y , z ) (x,y,z) ( x , y , z ) 是網格頂點靜止時的位置。我們在頂點着色器實現這n n n 個擺動波的疊加,從前面生成的1 D 1D 1 D 紋理採樣( h i , ω i , k i ) (h_i,\omega_i,k_i) ( h i , ω i , k i ) 。 t t t 是時間點,隨着時間推移,波浪圍繞着靜止時的位置做圓周運動。
④網格頂點法線 :
我們通過沿x x x 軸的切線、沿z z z 軸的切線的叉乘來求得當前頂點的法向量。爲此,我們分別對式(13)求關於x x x 的偏導、關於z z z 的偏導。
與頂點位置的計算一樣,我們同樣要過濾掉波長小於N m i n ∗ l N_{min}*l N m i n ∗ l 的擺動波(這裏l l l 爲屏幕空間中網格的大小,注意與L L L 區分),爲此設濾波權重w n , i w_{n,i} w n , i :
w n , i ( N m i n , N m a x , λ i / l ) = c l a m p ( λ i / l − N m i n N m a x − N m i n , 0 , 1 ) w_{n,i}(N_{min},N_{max},\lambda_i/l)=clamp(\frac{\lambda_i/l-N_{min}}{N_{max}-N_{min}},0,1) w n , i ( N m i n , N m a x , λ i / l ) = c l a m p ( N m a x − N m i n λ i / l − N m i n , 0 , 1 ) (14)
將頂點位置中的w p , i w_{p,i} w p , i 用w n , i w_{n,i} w n , i 替換。
求解P P P 關於x x x 的偏導數,沿x x x 軸的切向量:
p h a s e = ω i t − k i ⋅ ( x , z ) phase=\omega_it-k_i\cdot(x,z) p h a s e = ω i t − k i ⋅ ( x , z )
∂ P ∂ x = ( ∂ X ∂ x , ∂ Y ∂ x , ∂ Z ∂ x ) \frac{\partial P}{\partial x}=(\frac{\partial X}{\partial x},\frac{\partial Y}{\partial x},\frac{\partial Z}{\partial x}) ∂ x ∂ P = ( ∂ x ∂ X , ∂ x ∂ Y , ∂ x ∂ Z )
∂ X ∂ x = 1 + Σ 1 n w n , i h i c o s θ i c o s ( p h a s e ) ( − k i , x ) \frac{\partial X}{\partial x}=1+\Sigma_1^nw_{n,i}h_icos\theta_icos(phase)(-k_{i,x}) ∂ x ∂ X = 1 + Σ 1 n w n , i h i c o s θ i c o s ( p h a s e ) ( − k i , x ) (15)
∂ Y ∂ x = 0 + Σ 1 n w n , i h i [ − s i n ( p h a s e ) ] ( − k i , x ) \frac{\partial Y}{\partial x}=0+\Sigma_1^nw_{n,i}h_i[-sin(phase)](-k_{i,x}) ∂ x ∂ Y = 0 + Σ 1 n w n , i h i [ − s i n ( p h a s e ) ] ( − k i , x )
∂ Z ∂ x = 0 + Σ 1 n w n , i h i c o s θ i c o s ( p h a s e ) ( − k i , x ) \frac{\partial Z}{\partial x}=0+\Sigma_1^nw_{n,i}h_icos\theta_icos(phase)(-k_{i,x}) ∂ x ∂ Z = 0 + Σ 1 n w n , i h i c o s θ i c o s ( p h a s e ) ( − k i , x )
求解P P P 關於z z z 的偏導數,沿y y y 軸的切向量:
∂ P ∂ z = ( ∂ X ∂ z , ∂ Y ∂ z , ∂ Z ∂ z ) \frac{\partial P}{\partial z}=(\frac{\partial X}{\partial z},\frac{\partial Y}{\partial z},\frac{\partial Z}{\partial z}) ∂ z ∂ P = ( ∂ z ∂ X , ∂ z ∂ Y , ∂ z ∂ Z )
∂ X ∂ z = 0 + Σ 1 n w n , i h i c o s θ i c o s ( p h a s e ) ( − k i , z ) \frac{\partial X}{\partial z}=0+\Sigma_1^nw_{n,i}h_icos\theta_icos(phase)(-k_{i,z}) ∂ z ∂ X = 0 + Σ 1 n w n , i h i c o s θ i c o s ( p h a s e ) ( − k i , z ) (16)
∂ Y ∂ z = 0 + Σ 1 n w n , i h i [ − s i n ( p h a s e ) ] ( − k i , z ) \frac{\partial Y}{\partial z}=0+\Sigma_1^nw_{n,i}h_i[-sin(phase)](-k_{i,z}) ∂ z ∂ Y = 0 + Σ 1 n w n , i h i [ − s i n ( p h a s e ) ] ( − k i , z )
∂ Z ∂ z = 1 + Σ 1 n w n , i h i c o s θ i c o s ( p h a s e ) ( − k i , z ) \frac{\partial Z}{\partial z}=1+\Sigma_1^nw_{n,i}h_icos\theta_icos(phase)(-k_{i,z}) ∂ z ∂ Z = 1 + Σ 1 n w n , i h i c o s θ i c o s ( p h a s e ) ( − k i , z )
從而,結合式(15)、式(16),我們得頂點的法向量如下:
N = ∂ P ∂ x × ∂ P ∂ z N=\frac{\partial P}{\partial x}\times\frac{\partial P}{\partial z} N = ∂ x ∂ P × ∂ z ∂ P (17)
⑤網格頂點斜率方差 :
爲了計算海面的B R D F BRDF B R D F 函數,我們需要頂點的一些統計學性質來捕捉海水亞像素表面的細節。不同波長的擺動波序列可被視爲獨立的隨機變量,根據中心極限定理,許多這樣的擺動波疊加構成了一個表面,這個表面的斜率遵從高斯分佈,斜率的方差是每個擺動波斜率方差之和。
σ x 2 = Σ 1 n k i , x ∣ ∣ k i ∣ ∣ 2 ( 1 − 1 − ∣ ∣ k i ∣ ∣ 2 w r 2 h i 2 ) \sigma_x^2=\Sigma_1^n\frac{k_{i,x}}{||k_i||^2}(1-\sqrt{1-||k_i||^2w_r^2h_i^2}) σ x 2 = Σ 1 n ∣ ∣ k i ∣ ∣ 2 k i , x ( 1 − 1 − ∣ ∣ k i ∣ ∣ 2 w r 2 h i 2 )
σ z 2 = Σ 1 n k i , z ∣ ∣ k i ∣ ∣ 2 ( 1 − 1 − ∣ ∣ k i ∣ ∣ 2 w r 2 h i 2 ) \sigma_z^2=\Sigma_1^n\frac{k_{i,z}}{||k_i||^2}(1-\sqrt{1-||k_i||^2w_r^2h_i^2}) σ z 2 = Σ 1 n ∣ ∣ k i ∣ ∣ 2 k i , z ( 1 − 1 − ∣ ∣ k i ∣ ∣ 2 w r 2 h i 2 ) (18)
其中σ x 2 \sigma_x^2 σ x 2 、σ z 2 \sigma_z^2 σ z 2 是沿着x x x 軸、z z z 軸的斜率方差,而w r = 1 − w n w_r=1-w_n w r = 1 − w n 。在實現中,我們是沿着風向以及垂直於風向的兩個方向軸計算這兩個方差,這兩個方向軸對應斜率橢圓高斯分佈的軸。
海水的BRDF模型
在海洋光學中,Ross等人推出了一個針對各項異性表面且斜率和高度遵從高斯分佈的B R D F BRDF B R D F 模型。對於一個給定斜率ζ \zeta ζ 的微平面,他們採用Smith的shadowing因子來推算這個微平面對於視線v v v 和光線l l l 均可見的概率。
q v n ( ζ , v , l ) = p ( ζ ) m a x ( v ⋅ f , 0 ) H ( l ⋅ f ) 1 + ⋀ ( a v ) + ⋀ ( a l ) ) f z c o s θ v d 2 ζ q_{vn}(\zeta,v,l)=\frac{p(\zeta)max(v\cdot f,0)H(l\cdot f)}{1+\bigwedge(a_v)+\bigwedge(a_l))f_zcos\theta_v}d^2\zeta q v n ( ζ , v , l ) = 1 + ⋀ ( a v ) + ⋀ ( a l ) ) f z c o s θ v p ( ζ ) m a x ( v ⋅ f , 0 ) H ( l ⋅ f ) d 2 ζ (19)
f ( ζ ) = [ f x , f y , f z ] T = 1 1 + ζ x 2 + ζ y 2 [ − ζ x , − ζ y , 1 ] T f(\zeta)=[f_x,f_y,f_z]^T=\frac{1}{\sqrt{1+\zeta_x^2+\zeta_y^2}}[-\zeta_x,-\zeta_y,1]^T f ( ζ ) = [ f x , f y , f z ] T = 1 + ζ x 2 + ζ y 2 1 [ − ζ x , − ζ y , 1 ] T (20)
p ( ζ ) = 1 2 π σ x σ y e x p ( − 1 2 ( ζ x 2 σ x 2 + ζ y 2 σ y 2 ) ) p(\zeta)=\frac{1}{2\pi\sigma_x\sigma_y}exp(-\frac12(\frac{\zeta_x^2}{\sigma_x^2}+\frac{\zeta_y^2}{\sigma_y^2})) p ( ζ ) = 2 π σ x σ y 1 e x p ( − 2 1 ( σ x 2 ζ x 2 + σ y 2 ζ y 2 ) ) (21)
⋀ ( a i ) = e x p ( − a i 2 ) − a i π e r f c ( a i ) 2 a i π , i ∈ { v , l } \bigwedge(a_i)=\frac{exp(-a_i^2)-a_i\sqrt{\pi}erfc(a_i)}{2a_i\sqrt\pi},i\in\{v,l\} ⋀ ( a i ) = 2 a i π e x p ( − a i 2 ) − a i π e r f c ( a i ) , i ∈ { v , l } (22)
a i = ( 2 ( σ x 2 c o s 2 ϕ i + σ y 2 s i n 2 ϕ i ) t a n θ i ) − 1 / 2 a_i=(2(\sigma_x^2cos^2\phi_i+\sigma_y^2sin^2\phi_i)tan\theta_i)^{-1/2} a i = ( 2 ( σ x 2 c o s 2 ϕ i + σ y 2 s i n 2 ϕ i ) t a n θ i ) − 1 / 2 (23)
座標系如上圖所示(注意與前面的區分)。對於一個方向向量,我們用( θ , ϕ ) (\theta,\phi) ( θ , ϕ ) 來表示,前者爲天頂角,後者爲方位角。ζ = ( ζ x , ζ y ) \zeta=(\zeta_x,\zeta_y) ζ = ( ζ x , ζ y ) 表示一個微平面在x x x 軸、y y y 軸的斜率,對於給定的微平面斜率ζ \zeta ζ ,我們有微平面法線f ( ζ ) f(\zeta) f ( ζ ) 即式(20),注意與宏觀表面法線區分。式(21)即p ( ζ ) p(\zeta) p ( ζ ) 就是我們比較熟悉的二維高斯分佈函數,這個函數是關於斜率的高斯分佈函數。函數⋀ ( a i ) \bigwedge(a_i) ⋀ ( a i ) 來源於Smith的shadowing因子。式(19)中的H ( l ⋅ f ) H(l\cdot f) H ( l ⋅ f ) 是海維賽德函數(Heaviside函數),它的定義如下:
H ( x ) = { 0 , x ≤ 0 1 , x > 0 H(x)=\begin{cases} 0,x\leq0 \\ 1,x>0 \end{cases} H ( x ) = { 0 , x ≤ 0 1 , x > 0 (24)
如果我們忽略多重反射並假設微平面都完美的鏡面的話,設h h h 是向量v v v 和向量l l l 之間的半角向量(即v v v 和l l l 以h h h 對稱),ζ g \zeta_g ζ g 是以h爲法線的微平面的斜率(我們以微平面的斜率表示一個微平面),那麼B R D F BRDF B R D F 函數就是微平面ζ h \zeta_h ζ h 的可見性概率乘上菲涅爾反射因子F F F :
d 2 ζ = s i n θ l d θ l d ϕ l 4 h z 3 v ⋅ h = d 2 ω l 4 h z 3 v ⋅ h d^2\zeta=\frac{sin\theta_ld\theta_ld\phi_l}{4h_z^3v\cdot h}=\frac{d^2\omega_l}{4h_z^3v\cdot h} d 2 ζ = 4 h z 3 v ⋅ h s i n θ l d θ l d ϕ l = 4 h z 3 v ⋅ h d 2 ω l
b r d f ( v , l ) = q v n ( ζ h , v , l ) F ( v ⋅ h ) 4 h z 3 c o s θ l v ⋅ h brdf(v,l)=\frac{q_{vn}(\zeta_h,v,l)F(v\cdot h)}{4h_z^3cos\theta_lv\cdot h} b r d f ( v , l ) = 4 h z 3 c o s θ l v ⋅ h q v n ( ζ h , v , l ) F ( v ⋅ h ) (25)
①太陽反射光 :
對於太陽反射光,我們採用Schlick模型作爲菲涅爾反射因子:
F ( v ⋅ h ) ≈ R + ( 1 − R ) ( 1 − v ⋅ h ) 5 F(v\cdot h)\approx R+(1-R)(1-v\cdot h)^5 F ( v ⋅ h ) ≈ R + ( 1 − R ) ( 1 − v ⋅ h ) 5 (26)
其中R R R 是一個常係數,在實現中取R = 0.02 R=0.02 R = 0 . 0 2 。在整個太陽的立體角Ω s u n \Omega_{sun} Ω s u n 中我們把B R D F BRDF B R D F 看作一個常數,避免積分計算。因此反射的太陽光輻射率如下:
I s u n = ∬ b r d f ( v , l ) L s u n c o s θ l d 2 ω l ≈ L s u n Ω s u n p ( ζ h ) R + ( 1 − R ) ( 1 − v ⋅ h ) 5 4 h z 4 c o s θ v ( 1 + ⋀ ( a v ) + ⋀ ( a l ) ) I_{sun}=\iint brdf(v,l)L_{sun}cos\theta_ld^2\omega_l\approx L_{sun}\Omega_{sun}p(\zeta_h)\frac{R+(1-R)(1-v\cdot h)^5}{4h_z^4cos\theta_v(1+\bigwedge(a_v)+\bigwedge(a_l))} I s u n = ∬ b r d f ( v , l ) L s u n c o s θ l d 2 ω l ≈ L s u n Ω s u n p ( ζ h ) 4 h z 4 c o s θ v ( 1 + ⋀ ( a v ) + ⋀ ( a l ) ) R + ( 1 − R ) ( 1 − v ⋅ h ) 5 (27)
其中L s u n L_{sun} L s u n 爲太陽輻射率,其他參數前面都已經提到。整個b r d f brdf b r d f 的計算我們是在切線空間中進行(以宏觀法線爲z z z 軸),關於計算太陽反射光輻射率的僞代碼如下所示:
②天空反射光 :
微平面的B R D F BRDF B R D F 模型都有相似的表達式,這個表達式表明B R D F BRDF B R D F 與法線爲半角向量的微平面所佔的比重成比例(假設忽略多重反射),記ρ \rho ρ 爲比例係數,我們有:
b r d f ( v , l ) = p ( ζ h ) ρ ( v , l ) brdf(v,l)=p(\zeta_h)\rho(v,l) b r d f ( v , l ) = p ( ζ h ) ρ ( v , l ) (28)
在切線空間計算天空反射光的積分公式則爲(對整個半球方向積分):
I s k y = ∬ Ω p ( ζ h ) ρ ( v , l ) L s k y ( l ) c o s θ l d 2 ω l I_{sky}=\iint_\Omega p(\zeta_h)\rho(v,l)L_{sky}(l)cos\theta_ld^2\omega_l I s k y = ∬ Ω p ( ζ h ) ρ ( v , l ) L s k y ( l ) c o s θ l d 2 ω l (29)
L s k y ( l ) L_{sky}(l) L s k y ( l ) 表示從方向l l l 接收的天空輻射率,做一些轉換:
d 2 ω l = 4 h z 3 v ⋅ h d 2 ζ d^2\omega_l=4h_z^3v\cdot hd^2\zeta d 2 ω l = 4 h z 3 v ⋅ h d 2 ζ
r ( v , ζ ) = 2 ( v ⋅ f ( ζ ) ) f ( ζ ) − v = [ r x , r y , r z ] T r(v,\zeta)=2(v\cdot f(\zeta))f(\zeta)-v=[r_x,r_y,r_z]^T r ( v , ζ ) = 2 ( v ⋅ f ( ζ ) ) f ( ζ ) − v = [ r x , r y , r z ] T (30)
ρ ′ ( v , ζ ) = 4 h z 3 v ⋅ f ( ζ ) r z ρ ( v , r ( v , ζ ) ) \rho^{'}(v,\zeta)=4h_z^3v\cdot f(\zeta)r_z\rho(v,r(v,\zeta)) ρ ′ ( v , ζ ) = 4 h z 3 v ⋅ f ( ζ ) r z ρ ( v , r ( v , ζ ) )
我們將式(29)變換成:
I s k y = ∬ − ∞ + ∞ p ( ζ ) ρ ′ ( v , ζ ) L s k y ( r ) H ( r z ) d 2 ζ I_{sky}=\iint_{-\infty}^{+\infty}p(\zeta)\rho^{'}(v,\zeta)L_{sky}(r)H(r_z)d^2\zeta I s k y = ∬ − ∞ + ∞ p ( ζ ) ρ ′ ( v , ζ ) L s k y ( r ) H ( r z ) d 2 ζ (31)
這裏我們將光線方向l l l 換成了r ( v , ζ ) r(v,\zeta) r ( v , ζ ) ,即 視線沿斜率爲ζ \zeta ζ 的微平面的反射向量。而H ( r z ) H(r_z) H ( r z ) 即公式(24)的海維賽德函數,其中傳入的參數r z r_z r z 爲r ( v , ζ ) r(v,\zeta) r ( v , ζ ) 向量的天頂角c o s cos c o s 值,通過海維賽德函數我們把積分範圍限制在了半球方向內。式(30)和式(31)中的符號前面都已經提到過,不再贅述。
然後論文指出,如果p ( ζ ) p(\zeta) p ( ζ ) 影響很小,即BRDF波瓣狹窄,那麼公式(31)可近似擬合成下面兩項平均值之積:
I s k y ≈ F ‾ ⋅ L ‾ I_{sky}\approx \overline F \cdot \overline L I s k y ≈ F ⋅ L
F ‾ ( v ) = ∬ − ∞ + ∞ p ( ζ ) ρ ′ ( v , ζ ) H ( r z ) d 2 ζ \overline F(v)=\iint_{-\infty}^{+\infty}p(\zeta)\rho^{'}(v,\zeta)H(r_z)d^2\zeta F ( v ) = ∬ − ∞ + ∞ p ( ζ ) ρ ′ ( v , ζ ) H ( r z ) d 2 ζ (32)
L ‾ ( v ) = ∬ − ∞ + ∞ p ( ζ ) L s k y ( r ) H ( r z ) d 2 ζ \overline L(v)=\iint_{-\infty}^{+\infty}p(\zeta)L_{sky}(r)H(r_z)d^2\zeta L ( v ) = ∬ − ∞ + ∞ p ( ζ ) L s k y ( r ) H ( r z ) d 2 ζ (33)
接下來就是我們要怎麼計算這兩項平均值。
1)、平均菲涅爾反射 :
由Ross的B R D F BRDF B R D F 模型以及公式(32),有:
F ‾ ( v ) = ∬ − ∞ + ∞ q v n ( ζ , v , r ) F ( v ⋅ h ) H ( r z ) d 2 ζ \overline F(v)=\iint_{-\infty}^{+\infty}q_{vn}(\zeta,v,r)F(v\cdot h)H(r_z)d^2\zeta F ( v ) = ∬ − ∞ + ∞ q v n ( ζ , v , r ) F ( v ⋅ h ) H ( r z ) d 2 ζ (34)
上述公式可看成是有效菲涅爾反射或者平均菲涅爾反射。論文實踐嘗試指出,公式(34)中的q v n q_{vn} q v n 可用q v n e q_{vn}^e q v n e 近似,然後採用Schlick模型,我們有:
q v n e ( ζ , v ) = p ( ζ ) m a x ( v ⋅ f , 0 ) ( 1 + ⋀ ( a v ) ) f z c o s θ v d 2 ζ q_{vn}^e(\zeta,v)=\frac{p(\zeta)max(v\cdot f,0)}{(1+\bigwedge(a_v))f_zcos\theta_v}d^2\zeta q v n e ( ζ , v ) = ( 1 + ⋀ ( a v ) ) f z c o s θ v p ( ζ ) m a x ( v ⋅ f , 0 ) d 2 ζ
F ‾ ( v ) ≈ R + ( 1 − R ) ∬ − ∞ + ∞ q v n e ( ζ , v ) ( 1 − v ⋅ h ) 5 d 2 ζ \overline F(v)\approx R+(1-R)\iint_{-\infty}^{+\infty}q_{vn}^e(\zeta,v)(1-v\cdot h)^5d^2\zeta F ( v ) ≈ R + ( 1 − R ) ∬ − ∞ + ∞ q v n e ( ζ , v ) ( 1 − v ⋅ h ) 5 d 2 ζ (35)
其中R R R 和前面一樣,我們取R = 0.02 R=0.02 R = 0 . 0 2 。式(35)中剩餘的積分項取決於σ x \sigma_x σ x 、σ y \sigma_y σ y 和v。然而當σ x \sigma_x σ x ,σ y \sigma_y σ y 均小於0.5 0.5 0 . 5 時,該積分項主要取決於θ v \theta_v θ v 和視線方向上的斜率方差σ v \sigma_v σ v :
σ v 2 = σ x 2 c o s 2 ϕ v + σ y 2 s i n 2 ϕ v \sigma_v^2=\sigma_x^2cos^2\phi_v+\sigma_y^2sin^2\phi_v σ v 2 = σ x 2 c o s 2 ϕ v + σ y 2 s i n 2 ϕ v (36)
其中θ v \theta_v θ v 和ϕ v \phi_v ϕ v 爲前面提到的視線的天頂角、方位角。最後,論文作者在實驗中推出了一個式(35)的近似擬合函數:
F ‾ ( v ) ≈ R + ( 1 − R ) ( 1 − c o s θ v ) 2 e x p ( − 2.69 σ v ) 1 + 22.7 σ v 1.5 \overline F(v)\approx R+(1-R)\frac{(1-cos\theta_v)^{2exp(-2.69\sigma_v)}}{1+22.7\sigma_v^{1.5}} F ( v ) ≈ R + ( 1 − R ) 1 + 2 2 . 7 σ v 1 . 5 ( 1 − c o s θ v ) 2 e x p ( − 2 . 6 9 σ v ) (37)
2)、平均天空輻射率 :
爲了計算平均天空反射輻射率我們丟棄公式(33)中的海維賽德函數H ( r z ) H(r_z) H ( r z ) ,天空輻射率L s k y L_{sky} L s k y 存儲在一張2 D 2D 2 D 紋理中,從而我們可以通過以濾波核函數p p p 對紋理L s k y L_{sky} L s k y 進行各項異性的紋理採樣來計算平均天空輻射率L ‾ \overline L L 。
記u ( v , ζ ) = U ( R ( r ( v , ζ ) ) ) u(v,\zeta)=U(R(r(v,\zeta))) u ( v , ζ ) = U ( R ( r ( v , ζ ) ) ) 爲將微平面斜率ζ \zeta ζ 映射到紋理座標u u u 的函數,r ( v , ζ ) r(v,\zeta) r ( v , ζ ) 爲視線在微平面ζ \zeta ζ 上的反射向量,R R R 則將反射向量從切線空間轉換到世界空間。爲了儘可能減少拉伸變形,論文作者發現採用極射赤平投影效果最佳,即:
u = [ r x , r y ] T / ( 1 + r z ) u=[r_x,r_y]^T/(1+r_z) u = [ r x , r y ] T / ( 1 + r z ) (38)
其中( r x , r y , r z ) (r_x,r_y,r_z) ( r x , r y , r z ) 是r ( v , ζ ) r(v,\zeta) r ( v , ζ ) 得出的反射向量。而關於如何以濾波核函數p p p 對紋理L s k y L_{sky} L s k y 進行各項異性的紋理採樣的推導我也看得是一知半解,大致就是如何近似逼近高斯分佈的橢圓區域以此從紋理採樣,實際上我的實現也並未濾波。
L ‾ ≈ t e x 2 D ( L s k y , u ( v , 0 ) , 2 σ x ∂ u ∂ ζ x ( v , 0 ) , 2 σ y ∂ u ∂ ζ y ( v , 0 ) ) \overline L\approx tex2D(L_{sky},u(v,0),2\sigma_x\frac{\partial u}{\partial \zeta_x}(v,0),2\sigma_y\frac{\partial u}{\partial \zeta_y}(v,0)) L ≈ t e x 2 D ( L s k y , u ( v , 0 ) , 2 σ x ∂ ζ x ∂ u ( v , 0 ) , 2 σ y ∂ ζ y ∂ u ( v , 0 ) ) (39)
這裏t e x 2 D tex2D t e x 2 D 可以直接採用GLSL的t e x t u r e G r a d textureGrad t e x t u r e G r a d 函數。
③海水折射光 :
從太陽和天空接收的光線在水中會發生折射,除去被吸收的光線外,經過多重散射後光線會再次地從水面輻射出來抵達視野。在深水區域中多重散射起主要作用,因爲我們把從水下散射出的輻射率看作漫反射光,基於這個前提假設以及能量守恆定律,我們取海水折射光的菲涅爾因子爲( 1 − F ‾ ) (1-\overline F) ( 1 − F ) 。則海水折射光近似爲以下:
I s e a = L s e a ( 1 − F ‾ ) I_{sea}=L_{sea}(1-\overline F) I s e a = L s e a ( 1 − F ) (40)
其中L s e a L_{sea} L s e a 爲海水本身的輻射率,即海水的顏色。式(40)中的( 1 − F ‾ ) (1-\overline F) ( 1 − F ) 意義即除去反射光線外,剩下的光線進入水中發生多重散射。
綜合①②③三部分,海水光照的僞代碼如下:
其中,傳入的參數v , l , n , t x , t y v,l,n,t_x,t_y v , l , n , t x , t y 是在世界空間的單位向量,而σ x 2 , σ y 2 \sigma_x^2,\sigma_y^2 σ x 2 , σ y 2 則是沿着切線方向t x t_x t x 和t y t_y t y 的斜率方差。
實現結果
大部分核心算法都是在GPU中實現的。在頂點着色器將屏幕空間的網格投影到世界空間,計算每個頂點的波浪偏移量(從P-M海浪譜採樣),然後再將其投影到屏幕空間。在片元着色器中,計算逐像素的法向量以及太陽反射光、天空反射光和海水折射光。在CPU端預先反演P-M海浪譜,隨機生成一組( h i , ω i , k i ) (h_i,\omega_i,k_i) ( h i , ω i , k i ) 存儲到1 D 1D 1 D 紋理中供頂點着色器採樣。
①實驗平臺 :
操作系統:Windows8.1
IDE工具:Qt Creator
語言:C++
API接口:OpenGL3.3+, Qt 5.7
②參數設置 :
奈奎斯特界限:( N m i n , N m a x ) = ( 0.1 f , 2.5 f ) (N_{min},N_{max})=(0.1f,2.5f) ( N m i n , N m a x ) = ( 0 . 1 f , 2 . 5 f )
波形疊加數:n u m W a v e s = 60 numWaves=60 n u m W a v e s = 6 0
波頻散:w a v e D i s p e r s i o n = 1.25 f waveDispersion=1.25f w a v e D i s p e r s i o n = 1 . 2 5 f
波幅:a m p l i t u d e = 0.96 f amplitude=0.96f a m p l i t u d e = 0 . 9 6 f
單元網格大小:g r i d S i z e = 2.0 f gridSize=2.0f g r i d S i z e = 2 . 0 f
波長界限:( l a m b d a _ m i n , l a m b d a _ m a x ) = ( 0.02 f , 30.0 f ) (lambda\_min,lambda\_max)=(0.02f,30.0f) ( l a m b d a _ m i n , l a m b d a _ m a x ) = ( 0 . 0 2 f , 3 0 . 0 f )
海面風速:U 0 = 10.0 f U0=10.0f U 0 = 1 0 . 0 f
hdr曝光度:h d r E x p o s u r e = 0.4 f hdrExposure=0.4f h d r E x p o s u r e = 0 . 4 f
③實現結果 :
1)、海水折射光、太陽反射光、天空反射光、全部光效混合分別如下所示。
2)、太陽不同位置的效果:
3)、高空俯瞰:
4)、網格的精度影響也挺大的:
從左到右,網格單元大小越來越大,因而精度越來越低,海面細節越來越粗糙。
5)、其他的一些截圖:
參考文獻
1、Eric Bruneton, Fabrice Neyret, and Nicolas Holzschuch, (2010) Real-time Realistic Ocean Lighting using Seamless Transitions from Geometry to BRDF, In EUROGRAPHICS 2010 Volume 29 (2010), Number 2.
2、ROSS V., DION D., POTVIN G.: Detailed analytical approach to the gaussian surface bidirectional reflectance distribution function specular component applied to the sea surface.Journal of Optical Society of America A 22 (Nov. 2005), 2442–2453.
3、HINSINGER D., NEYRET F., CANI M.-P.: Interactive animation of ocean waves. In Symposium on Computer Animation (2002), pp. 161–166.
4、劉潔, 鄒北驥, 周潔瓊, et al. 基於海浪譜的Gerstner波浪模擬[J]. 計算機工程與科學, 2006, 28(2).
5、張文橋. 動態海浪建模與仿真的關鍵技術研究[D], 2017.