这里依然用的是vertex 和fragment shader来解决水的反射的问题。
首先,准备两个平面,一个平面作为底图,一个平面模拟水的波动。这里要用到抓取底图的通道 GrabPass{}。然后把抓取的通道图放到水面的那张图上。另外一个难点就是要模拟水的波动,水的波动的原理如下图:
其中顶点函数代码和片段函数代码如下:
v2f vert(appdata v){
float w=2*3.1415926/_L
float f=_S*w
v.vertex.y+=_A*sin(v.vertex.xz*w+_Time.x*f)
v2f o
o.pos=mul(UNITY_MATRIX_MVP,v.vertex)
o.uv=TRANSFORM_TEX(v.uv,_MainTex)
o.proj=ComputeGrabScreenPos(o.pos)
return o
}
float4 frag(v2f IN):SV_Target{
IN.proj.xy+=0.01*sin(IN.proj.xy*3.14*10+_Time.y*2)
float4 col=tex2Dproj(_GrabTexture,IN.proj)*0.5
return col
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
如果想最后的贴图是随着法线变化,那么就要用到偏导数,计算每个顶点的动态法线。
v2f vert(appdata v){
float w=2*3.1415926/_L
float f=_S*w
v.vertex.y+=_A*sin(-length(v.vertex.xz)*w+_Time.x*f)
float dx=_A*v.vertex.x*w*cos(-length(v.vertex.xz)*w+_Time.x*f)
float dz=_A*v.vertex.z*w*cos(-length(v.vertex.xz)*w+_Time.x*f)
float3 B=normalize(float3(1,dx,0))
float3 T=normalize(float3(0,dz,1))
v2f o
o.N=cross(B,T)
o.pos=mul(UNITY_MATRIX_MVP,v.vertex)
o.uv=TRANSFORM_TEX(v.uv,_MainTex)
o.proj=ComputeGrabScreenPos(o.pos)
return o
}
float4 frag(v2f IN):SV_Target{
float d=dot(IN.N,float3(0,1,0))
IN.proj.xy+=d*0.1
//IN.proj.xy+=0.01*sin(IN.proj.xy*3.14*10+_Time.y*2)
float4 col=tex2Dproj(_GrabTexture,IN.proj)*0.5
return col
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
以上还不算完美,可以加上漫反射,让水的颜色随着波纹变化。
v2f vert(appdata v){
float w=2*3.1415926/_L
float f=_S*w
v.vertex.y+=_A*sin(-length(v.vertex.xz)*w+_Time.x*f)
float dx=_A*v.vertex.x*w*cos(-length(v.vertex.xz)*w+_Time.x*f)
float dz=_A*v.vertex.z*w*cos(-length(v.vertex.xz)*w+_Time.x*f)
float3 B=normalize(float3(1,dx,0))
float3 T=normalize(float3(0,dz,1))
v2f o
o.N=cross(B,T)
o.pos=mul(UNITY_MATRIX_MVP,v.vertex)
o.uv=TRANSFORM_TEX(v.uv,_MainTex)
o.proj=ComputeGrabScreenPos(o.pos)
return o
}
float4 frag(v2f IN):SV_Target{
float3 ncol=UnpackNormal(tex2D(_MainTex,IN.uv+_Time.x))*0.3
IN.N=IN.N+ncol
float d=dot(IN.N,float3(0,1,0))
float diff=max(0,dot(IN.N,float3(1,0,0)))
IN.proj.xy+=d*0.1
//IN.proj.xy+=0.01*sin(IN.proj.xy*3.14*10+_Time.y*2)
float4 col=tex2Dproj(_GrabTexture,IN.proj)*(0.3+diff)
return col
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
最终的效果: