Unity Shader:Waveform波形(3)-复合波

来源:互联网 发布:在excel中删除重复数据 编辑:程序博客网 时间:2024/05/22 06:47

1,2D复合波

这里写图片描述
(上图:在xy平面有三个波,y=sinx,y=sin2x,y=sin3x。)
可以将这三个波组合成一个复合波形,根据叠加原理(superposition principle),这个复合波既是三个波形相加后的结果:
y=sinx+sin2x+sin3x。
这里写图片描述

2,3D复合波

利用方向向量改变3D空间中一个平面的波形的方向

设任意一点点p,方向向量float2(1,0).
p.xy=dot(float2(1,0),p.xy)
再求它的正弦函数:
这里写图片描述
(上图,左手坐标系。z=sin(dot(float2(1,0),p.xy))
如果改变方向向量为0,1。p.xy=dot(float2(0,1),p.xy)
这里写图片描述
(上图,左手坐标系。z=sin(dot(float2(0,1),p.xy))
如果改变方向向量为(1,1)。p.xy=dot(float2(1,1),p.xy)
这里写图片描述
(上图,左手坐标系。z=sin(dot(float2(1,1),p.xy))
以上表明3D空间中的某个平面的每个点与一个方向向量进行点乘,那么通过这些点计算出的波形的方向与此向量的方向一致。在此可以将点乘理解为把方向向量的方向与强度赋予给一个点的集合。

3D空间中波的合成

在3D空间中,叠加原理依然适用:
这里写图片描述
(上图,左手坐标系,z=sin(y)+sin(x)+sin(x+y))

3,将复合波应用到复杂系统中

测试上文的波形

以下是Shader通过正弦函数的变种在片段着色器中重新计算像素位置与法线,并进行像素级光照后的效果。

这里写图片描述
将上面的1,0波应用到此系统中。
这里写图片描述
1,0波与0,1波合成。
这里写图片描述
(1,0),(0,1),和(1,1)波合成。

圆形波

思路与上文相同,只是波的方向不再是常数,在shader中计算波浪中心点,所有顶点根据此中心计算波的方向。
这里写图片描述
(上图:一个圆形波)
这里写图片描述
(上图:不同频率的两个圆形波合成)
这里写图片描述
(上图:不同频率的四个圆形波合成)
这里写图片描述
(上图:不同频率的四个圆形波合成。根据与波中心的距离衰减了波的力度,可更清楚看到波中心点)

通过这种波形组合再加上特定算法,在3D空间中可以进行一些复杂的模拟。

海浪与水纹

在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既是四个波的方向向量(x,y)。xzVtx保存的是世界空间的x,z坐标点。这样将世界空间中xz平面的每个点与4个方向向量进行点乘再相加计算高度offset.y,既完成了四个波的叠加。其中的amp,freq,speed等变量都是用来控制波形的形状(可见前篇文章)。

除了计算高度y值,上面的方法还根据Gerstner Wave公式对xz坐标也做了位移计算,形成了更加复杂的波形。此波形,既Gerstner波,的特点既是波峰处更加尖锐,xz坐标逐渐向波峰靠拢,与真实海洋波浪更加相近。

原始公式:(Jerry Tessendorf 2004)
x = x0 − (k/k)A sin(k · x0 − ωt)
y = A cos(k · x0 − ωt)
(再原始的公式尚未找到,尚未搞懂如何正确理解以上的xy坐标系。)

NVIDIA在GPU gems1 第一章中(equation 9)有将其展开成可以在3D空间中计算的函数,以上的算法基本与其一致。(尚未搞懂其函数从原始出处转换出来的方法与来源)

这里写图片描述
(上图:根据Gerstner Wave对以平面网格进行顶点位移以及光照)

这里写图片描述
(上图:Water4的海洋。海浪既是由Gerstner Wave计算得出)
实际效果对4个波形所给的参数也有相当的依赖。

将圆形波利用于折射特效:
这里写图片描述
(场景原图)
这里写图片描述
(一个波)
这里写图片描述
(一个波)
这里写图片描述
(两个波)
这里写图片描述
(两个波,平面顶点并没有产生变化,但立体感仍然很强)

————————————————————————————
参考:
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:更改一处笔误

原创粉丝点击