天天看點

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

2D複合波

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖1:在xy平面有三個波,y1=sinx,y2=sin2x,y3=sin3x)

根據疊加原理(superposition principle),可以将這三個波組合成一個複合波形,這個複合波既是三個波形相加後的結果:

y=sinx+sin2x+sin3x。

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖2:相加後生成的複合波)

3D複合波

利用方向向量改變3D空間中一個平面的波形的方向

設任意一點點p,方向向量a=float2(1,0).

p.xy=dot(float2(1,0),p.xy)

再求它的正弦函數:

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖3,左手坐标系。z=sin(dot(float2(1,0),p.xy))

如果改變方向向量a為0,1。p.xy=dot(float2(0,1),p.xy)

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖4,左手坐标系。z=sin(dot(float2(0,1),p.xy))

如果改變方向向量a為(1,1)。p.xy=dot(float2(1,1),p.xy)

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖5,左手坐标系。z=sin(dot(float2(1,1),p.xy))

以上表明3D空間中的某個平面的每個點在該平面的2D坐标與一個方向向量進行點乘,那麼通過這些點乘後的點與第三個次元的坐标所計算出的波形的方向與此向量的方向一緻。在此可以将點乘了解為把方向向量的方向與強度賦予給一個點的集合。

3D空間中波的合成

在3D空間中,疊加原理依然适用:

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖6,左手坐标系,z=sin(y)+sin(x)+sin(x+y))

将複合波應用到複雜系統中

測試上文的複合波形

以下是在Unity中用Shader通過正弦函數的變種在片段着色器中重新計算像素位置與法線,并進行正向光照計算後的效果。

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖7:一個xy點乘(1,0)的正弦函數波形)

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖8:一個xy點乘(1,0)與一個xy點乘(0,1)的複合正弦函數波形)

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖8:xy點乘(1,0),(0,1),(1,1)後的三個波形組成的複合波形)

圓形波

通過上文的方向波可知,利用一個方向向量可以将改變波形的方向,那麼圓形波的特點是任意一點的波形方向都是波形中心點射向該點的方向。利用Shader的并發程式設計特性,可以很友善的用目前像素坐标減去波形中心點坐标即可得出需要的方向向量。

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖9:一個圓形波)

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖10:不同頻率與位置的兩個圓形波合成)

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖11:不同頻率與位置的四個圓形波合成)

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖12:不同頻率與位置的四個圓形波合成,根據波紋與波中心的距離對波的力度進行了衰減,可更清楚看到波中心點)

通過以上可得知,利用波形可疊加的特性,隻要有正确的方向向量,任何複雜波形都是可以模拟。

海浪與水紋

在Unity Standard Assets中的Water4水模拟項目中的Shader中有一段計算Gerstner wave的代碼,裡面有利用到複合波:

half3 GerstnerOffset4_Official (half2 xzVtx, half4 steepness, half4 amp, half4 freq, half4 speed, half4 dirAB, half4 dirCD)   
            {  
                half3 offsets;  
          
                half4 AB = steepness.xxyy * amp.xxyy * dirAB.xyzw;  
                half4 CD = steepness.zzww * amp.zzww * dirCD.xyzw;  
          
                half4 dotABCD = freq.xyzw * half4(dot(dirAB.xy, xzVtx), dot(dirAB.zw, xzVtx), dot(dirCD.xy, xzVtx), dot(dirCD.zw, xzVtx));  
                half4 TIME = _Time.yyyy * speed;  
          
                half4 COS = cos (dotABCD + TIME);  
                half4 SIN = sin (dotABCD + TIME);  
          
                offsets.x =dot(COS, half4(AB.xz, CD.xz));  
                offsets.z =dot(COS, half4(AB.yw, CD.yw));  
                offsets.y = dot(SIN, amp);  
  
                return offsets;           
            }  
           

以上的方法中利用了向量化計算,看起來不是很直覺。dirAB.xy,dirAB.zw,dirCD,xy,dirCD.zw分别是四個波的方向向量。xzVtx儲存的是世界空間的x,z坐标點。這樣将世界空間中xz平面的每個點與4個方向向量進行點乘,再用sin計算出第三次元的y的波形高度值儲存到SIN,offsets.y再次利用dot對4個波的高度偏移值進行相加,既完成了四個波的疊加。其中的amp,freq,speed等變量都是用來控制波形的形狀(可見前篇文章)。

除了計算高度y值,上面的方法還根據Gerstner Wave公式對xz坐标也做了位移計算,形成了更加複雜的波形。此波形,既Gerstner波的特點既是波峰處更加尖銳,xz坐标逐漸向波峰靠攏,與真實海洋波浪更加相近。

Gerstner Wave原始公式:(Jerry Tessendorf 2004)

x = x0 − (k/k)A sin(k · x0 − ωt)

y = A cos(k · x0 − ωt)

(更原始的公式尚未找到,尚未搞懂公式思路)

NVIDIA在GPU gems1 第一章中(equation 9)有将以上公式展開成可以在3D空間中計算的函數,與Unity Water4的算法基本一緻。(尚未搞懂其函數從原始函數轉換出來的方法與思路)

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖13:根據Gerstner Wave對一個簡單平面網格進行頂點位移)

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖14:Unity Water4的海洋渲染效果,海浪的效果既是依賴于Gerstner Wave的計算)

複合波與折射

将對圓形波的計算應用于法線的偏移,偏移後的法線用于折射采樣,再結合複合波的疊加,多個采樣後的顔色疊加同樣也可以呈現波形效果同時又呈現了一個空間扭曲的特效效果。

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖15:正常渲染的場景)

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖16:用一個圓形波的法線進行折射采樣)

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖17:用一個圓形波的法線進行折射采樣)

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖18:用兩個圓形波的法線進行折射采樣與疊加)

Unity Shader:Waveform波形(3)-複合波2D複合波3D複合波将複合波應用到複雜系統中

(圖19:用兩個圓形波的法線進行折射采樣與疊加,可看出平面頂點沒有變化,也沒有單獨對平面進行光照渲染,但是折射采樣疊加後的扭曲的場景所呈現出的波形形狀更加細節與立體)

————————————————————————————

參考:

Shader FX/Water4 — UNITY

GPU gems1 —Nvidia

-https://developer.nvidia.com/gpugems/GPUGems/gpugems_app01.html

Simulating Ocean Water —Jerry Tessendorf

-http://www-evasion.imag.fr/Membres/Fabrice.Neyret/NaturalScenes/fluids/water/waves/fluids-nuages/waves/Jonathan/articlesCG/simulating-ocean-water-01.pdf

維護日志:

2017-11-19:更改一處筆誤

2020-8-15:review