简易的波纹效果

💡 利用Sin周期函数,让顶点的Y轴进行波动

Shader "ShaderLearning/VertexShader/wave"
{
 Properties{
 _Amplitude("Amplitude",float)=1
 _Frequency("Frequency",Range(0,5))=1
 _Speed("_Speed",float)=1
 }

 SubShader
 {

 Pass
 {
 CGPROGRAM
 #pragma vertex vert
 #pragma fragment frag
 #include "UnityCG.cginc"

 float _Amplitude;
 float _Frequency;
 float _Speed;

 struct v2f
 {
 float4 vertex : POSITION;
 float4 color : COLOR;
 };



 v2f vert (appdata_base v)
 {
 float up =sin(v.vertex.x)+_Time.y;
 // float4x4 m={
 // 1,0,0,0,
 // 0,sin(up)/8+0.5,0,0,
 // 0,0,1,0,
 // 0,0,0,1
 // };//由于Plane模型顶点的y值都为0和矩阵相乘的结果也都为0,所以定位没有进行移动
 // v.vertex=mul(m,v.vertex);

 //A*sin(w*x+t)
 v.vertex.y+=_Amplitude*sin(v.vertex.z*_Frequency+_Time.y*_Speed);

 v2f o;
 o.vertex = UnityObjectToClipPos(v.vertex);

 o.color=fixed4(v.vertex.y,v.vertex.y,v.vertex.y,1);
 return o;
 }

 fixed4 frag (v2f i) : COLOR
 {
 return i.color;
 }
 ENDCG
 }
 }
}

Screenshot 2023-03-13 at 11.43.22 PM.png

实现圆心波效果

💡 只需要计算顶点到圆心的模长,传入sin周期函数

v.vertex.y+=_Amplitude*sin(-length(v.vertex.xz)*_Frequency+_Time.y*_Speed);

Screenshot 2023-03-13 at 11.48.37 PM.png

利用顶点x方向于z方向之和作为周期传入sin

v.vertex.y+=_Amplitude*sin((v.vertex.x+v.vertex.z)*_Frequency+_Time.y*_Speed);

Screenshot 2023-03-13 at 11.51.17 PM.png

简易水面波浪效果

Screenshot 2023-03-14 at 12.01.12 AM.png

💡 根据英伟达在早期的GPU编程精粹这样的数据当中有提到,仿真一个水波,要用到4个正弦波,在移动设备上可能运算量会很大 下面的示例demo,简化尝试将两个正弦波叠加

Shader "ShaderLearning/VertexShader/wave"
{
 Properties{
 _Amplitude("Amplitude",float)=1
 _Frequency("Frequency",Range(0,5))=1
 _Speed("_Speed",float)=1
 }

 SubShader
 {

 Pass
 {
 CGPROGRAM
 #pragma vertex vert
 #pragma fragment frag
 #include "UnityCG.cginc"

 float _Amplitude;
 float _Frequency;
 float _Speed;

 struct v2f
 {
 float4 vertex : POSITION;
 float4 color : COLOR;
 };



 v2f vert (appdata_base v)
 {
 float up =sin(v.vertex.x)+_Time.y;
 // float4x4 m={
 // 1,0,0,0,
 // 0,sin(up)/8+0.5,0,0,
 // 0,0,1,0,
 // 0,0,0,1
 // };//由于Plane模型顶点的y值都为0和矩阵相乘的结果也都为0,所以定位没有进行移动
 // v.vertex=mul(m,v.vertex);

 //A*sin(w*x+t)
 v.vertex.y+=_Amplitude*sin((v.vertex.x+v.vertex.z)*_Frequency+_Time.y*_Speed);
 v.vertex.y+=_Amplitude*sin((v.vertex.x-v.vertex.z)*_Frequency+_Time.w*_Speed);

 v2f o;
 o.vertex = UnityObjectToClipPos(v.vertex);

 o.color=lerp(fixed4(0,0.5,1,1),fixed4(1,1,1,1),v.vertex.y);
 return o;
 }

 fixed4 frag (v2f i) : COLOR
 {
 return i.color;
 }
 ENDCG
 }
 }
}