先放一个效果图
参数为:
Shader代码:
Shader "Custom/UnderWater" {
Properties {
_MainTex ("基础贴图 (RGB)", 2D) = "white" {}
_FlushTex ("水波贴图 (RGB)", 2D) = "white" {}
_FlowColor("水波颜色", Color) = (1,1,1,1)
_FlowSpeed("扫光速度", Range(0,1)) = 0.01
_TexSpeedX("UV流动速度X", Range(-1,1)) = 0.01
_TexSpeedY("UV流动速度Y", Range(-1,1)) = 0.01
_FlushLight("水波亮度", Range(0,10)) = 2
}
SubShader {
Pass
{
Tags { "Queue" = "Geometry" }
CGPROGRAM
#include "UnityCG.cginc"
#pragma vertex vert
#pragma fragment frag
struct v2f
{
float4 vertex:POSITION;
float2 uv:TEXCOORD0;
float nr:TEXCOORD1;
};
sampler2D _MainTex;
sampler2D _FlushTex;
float4 _FlowColor;
float _FlowRange;
float _FlowSpeed;
float _TexSpeedX;
float _TexSpeedY;
float _FlushLight;
v2f vert(appdata_base v)
{
v2f o;
o.uv = v.texcoord;
o.vertex = mul(UNITY_MATRIX_MVP,v.vertex);
float3 dir = normalize(float3(cos(_Time.x * _FlowSpeed),sin(_Time.y * _FlowSpeed),sin(_Time.z * _FlowSpeed)));
o.nr = dot(dir,v.normal);
return o;
}
fixed4 frag (v2f IN):COLOR
{
fixed fac = saturate(IN.nr * IN.nr );
fixed2 offset = float2(_Time.x * _TexSpeedX , _Time.x * _TexSpeedY);
half4 fluc = tex2D(_FlushTex,IN.uv + offset) * _FlowColor * _FlushLight ;
half4 c= fac*tex2D(_MainTex, IN.uv) * (1 - fac)*fluc;
return c;
}
ENDCG
}
}
FallBack "Diffuse"
}
在这个Shader中,主要是使用一张水波贴图来和模型原本贴图颜色进行叠加,来模拟模型在水下的颜色。
再读取水波贴图时,进行UV动画偏移,模拟水波在身上流动的效果。
最后,最重要的是水波流动时会在模型身上产生随机的阴影。该阴影需要随机、连续,并且有一定的周期性。
我们用三角函数生成了一个周期向量,为了体现差异性,每个向量使用的 _Time 尺度不同。
其中:
_Time.x = 1/20 t
_Time.y = t
_Time.z = 2t
_Time.w = 3t
然后我们用这个周期向量与模型空间下的法线的点乘,得到的结果用来当做水波阴影的系数。
float3 dir = normalize(float3(cos(_Time.x * _FlowSpeed),sin(_Time.y * _FlowSpeed),sin(_Time.z * _FlowSpeed)));
o.nr = dot(dir,v.normal);
为了增加差异性,这个系数在偏远着色器取了平方值。
fixed fac = saturate(IN.nr * IN.nr );
接下来取水波颜色
fixed2 offset = float2(_Time.x * _TexSpeedX , _Time.x * _TexSpeedY);
half4 fluc = tex2D(_FlushTex,IN.uv + offset) * _FlowColor * _FlushLight ;
这里使用了简单的UV动画,体现水波在模型身上的流动性。
关于UV动画,这里有介绍。
最后将模型原色和水波颜色进行叠加。
half4 c= fac*tex2D(_MainTex, IN.uv) * (1 - fac)*fluc;