【前置】
【效果】
【shader代码详解】
Shader "Custom/WaterFlow"
{
Properties{
_MainTex("MainTex",2D) = "white"{}//存放贴图
_Color("Color Tint",Color) = (1,1,1,1)//控制整体颜色
_Specular("Specular",Color) =(1,1,1,1)//控制高光反射颜色
_Gloss("Gloss",Range(1,100))=10//控制高光区域大小
_Magnitude("Magnitude",Float) = 0.1//控制波动频率
_Frequency("Frequency",Float) = 0.5//控制波动幅度,参考正弦波的频率幅度来理解
_Speed("Speed", Float) = 0.01//控制流动速度
_AlphaScale("Alpha Scale",Range(0,1)) = 0.65//透明度混合中的透明度系数
}
SubShader{
//指定透明度混合渲染队列、该Shader不受投影器影响、该Shader要使用透明度混合、顶点动画不能批处理
Tags{"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "DisableBatching" = "True"}
Pass{
//指定前向渲染模式
Tags{"LightMode" = "ForwardBase"}
ZWrite Off//关闭深度读写
Blend SrcAlpha OneMinusSrcAlpha//开启混合模式
Cull Off//关闭剔除功能
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
//定义Properties中的变量
sampler2D _MainTex;
float4 _MainTex_ST;//纹理的缩放和偏移值,TRANSFORM_TEX会调用
fixed4 _Color;
fixed4 _Specular;
float _Gloss;
float _Magnitude;
float _Frequency;
float _Speed;
float _AlphaScale;
struct a2v {
float4 vertex:POSITION;
float2 texcoord:TEXCOORD0;
float3 normal:NORMAL;
};
struct v2f {
float4 pos:SV_POSITION;
float2 uv:TEXCOORD0;//使用第一个插值寄存器
float3 worldNormal:TEXCOORD1;//使用第二个插值寄存器
float3 worldPos:TEXCOORD2;
};
v2f vert(a2v v) {
v2f o;
o.worldNormal = UnityObjectToWorldNormal(v.normal);//世界空间下顶点法线
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
float4 offset = float4(0, 0, 0, 0);//顶点偏移
offset.y = sin(_Frequency *_Time.y+ v.vertex.x+ v.vertex.y+ v.vertex.z)*_Magnitude;//顶线Y坐标随时间偏移
o.pos = UnityObjectToClipPos(v.vertex + offset);//顶点从模型空间到裁剪空间
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);//传递UV坐标
o.uv += float2(0, _Time.y*_Speed);//纹理动画,水平方向上的移动
return o;
}
fixed4 frag(v2f i) :SV_Target{
//计算漫反射
fixed3 worldNormal = normalize(i.worldNormal);//世界空间下顶点法线
fixed3 worldLight = UnityWorldSpaceLightDir(i.worldPos);//世界空间下顶点处的入射光
fixed4 texColor = tex2D(_MainTex, i.uv);
fixed3 albedo = texColor.rgb*_Color.rgb;//纹理采样获取漫反射颜色
fixed3 diffuse = _LightColor0.rgb * albedo * (dot(worldLight, worldNormal)*0.5 + 0.5);//半兰伯特模型计算漫反射
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;//环境光
//计算高光反射,冯氏模型
fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));//观察方向
fixed3 reflectDir = normalize(reflect(-worldLight, worldNormal));//计算反射方向
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir, viewDir)), _Gloss);
return fixed4(ambient + diffuse + specular,texColor.a*_AlphaScale);//改变透明通道的值
}
ENDCG
}
}
FallBack "Transparent/VertexLit"
}
【参考】
《shader入门精要》