眼睛部分单独作为一个材质球,准备一张睁眼一张闭眼的贴图,在shader中自动切换贴图,实现眨眼效果
Shader "MyShader/ChangeEmoji"
{
Properties
{
_MainTex ("Open Eye Tex", 2D) = "white" {}
_TargetTex ("Close Eye Tex", 2D) = "white" {}
_BlinkSpeed("Blink Speed",float) = 3
_BlinkRatio("Blink Ratio",float) = 0.05
}
SubShader
{
Tags
{
//渲染队列
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "TransparentCutout"
}
Pass
{
//光照模式
Tags { "LightMode"="ForwardBase" }
//关闭深度写入
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
//定义顶点/片元着色器代码
#pragma vertex vert
#pragma fragment frag
//包含内置文件
#include "Lighting.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _TargetTex;
float4 _TargetTex_ST;
float _BlinkSpeed;
float _BlinkRatio;
//定义顶点着色器的输入
struct a2v
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
//定义顶点着色器的输出、片元着色器的输入
struct v2f
{
float4 pos : SV_POSITION;
float3 worldNormal : TEXCOORD0;
float3 worldPos : TEXCOORD1;
float2 uv : TEXCOORD2;
};
v2f vert(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
//无论现实哪张贴图,都使用贴图_MainTex的uv坐标
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
//tex2D函数:对纹理进行采样,tex2D(采样的纹理, 纹理坐标)
//step函数,step(a, x) 等同于 (x >= a) ? 1 : 0
cos函数计算眨眼时间周期
//float cosValue = (cos(_Time.y*_BlinkSpeed)+1)*0.5;
//int stepValue = step(_BlinkRatio,cosValue);
//return tex2D(_MainTex, i.uv) * stepValue + tex2D(_TargetTex, i.uv) * (1-stepValue);
//_Time取余计算眨眼时间周期
//float timer = (_Time.y % _BlinkPeriod)
int stepValue = step(_BlinkTime,(_Time.y % _BlinkPeriod));
return tex2D(_MainTex, i.uv) * stepValue + tex2D(_TargetTex, i.uv) * (1-stepValue);
}
ENDCG
}
}
FallBack "Diffuse"
}
上面shader不支持Unity Fog,在原有基础上增加Fog效果,没有其他不同
Shader "MyShader/ChangeEmoji"
{
Properties
{
_MainTex ("Open Eye Tex", 2D) = "white" {}
_TargetTex ("Close Eye Tex", 2D) = "white" {}
_BlinkPeriod("Blink Period",float) = 3
_BlinkDuration("Blink Duration",float) = 0.2
}
SubShader
{
Tags
{
//渲染队列
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "TransparentCutout"
}
Pass
{
//光照模式
Tags { "LightMode"="ForwardBase" }
//关闭深度写入
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
//定义顶点/片元着色器代码
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _TargetTex;
float4 _TargetTex_ST;
float _BlinkPeriod;
float _BlinkDuration;
//定义顶点着色器的输入
struct a2v
{
float4 vertex : POSITION;
float4 texcoord : TEXCOORD0;
};
//定义顶点着色器的输出、片元着色器的输入
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 pos : SV_POSITION;
};
v2f vert(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
//无论现实哪张贴图,都使用贴图_MainTex的uv坐标
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
UNITY_TRANSFER_FOG(o,o.pos);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
//tex2D函数:对纹理进行采样,tex2D(采样的纹理, 纹理坐标)
//step函数,step(a, x) 等同于 (x >= a) ? 1 : 0
int stepValue = step(_BlinkDuration,(_Time.y % _BlinkPeriod));
fixed4 col = tex2D(_MainTex, i.uv) * stepValue + tex2D(_TargetTex, i.uv) * (1-stepValue);
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
FallBack "Diffuse"
}