shader中的序列帧动画属于纹理动画中的一种,主要原理是将给定的纹理进行等分,再根据时间的变化循环播放等分中的一部分。
Unity Shader 内置时间变量
名称
类型
描述
_Time
float4
(t/20,t,2t,3t) 其中t为自该场景加载所经过时间
_SinTime
float4
(t/8,t/4,t/2,t) 其中t为自该场景加载所经过时间的正弦值
_CosTime
float4
(t/8,t/4,t/2,t) 其中t为自该场景加载所经过时间的余弦值
unity_DeltaTime
float4
(dt,1/dt,sdt,1/sdt) 其中dt为时间增量,sdt为时间增量的平滑值
脚本如下:
1 Shader "MyUnlit/FrameAnimation"
2 {
3 Properties
4 {
5 _Color("Color Tint",color)=(1,1,1,1)
6 _MainTex ("Texture", 2D) = "white" {}
7 _CutX("CutX Amount",float)=4
8 _CutY("CutY Amount",float)=4
9 _Speed("Speed",range(1,100))=30
10 }
11 SubShader
12 {
13 //一般序列帧动画的纹理会带有Alpha通道,因此要按透明效果渲染,需要设置标签,关闭深度写入,使用并设置混合
14 Tags { "RenderType"="transparent" "queue"="transparent" "ignoreprojector"="true" }
15 ZWrite off
16 blend srcalpha oneminussrcalpha
17
18 Pass
19 {
20 Tags{"lightmode"="forwardbase"}
21
22 CGPROGRAM
23 #pragma vertex vert
24 #pragma fragment frag
25 #pragma multi_compile_fog
26
27 #include "UnityCG.cginc"
28
29 struct appdata
30 {
31 float4 vertex : POSITION;
32 float2 uv : TEXCOORD0;
33 };
34
35 struct v2f
36 {
37 float2 uv : TEXCOORD0;
38 UNITY_FOG_COORDS(1)
39 float4 vertex : SV_POSITION;
40 };
41
42 sampler2D _MainTex;
43 float4 _MainTex_ST;
44 fixed4 _Color;
45 float _CutX;
46 float _CutY;
47 float _Speed;
48
49 v2f vert (appdata v)
50 {
51 v2f o;
52 o.vertex = UnityObjectToClipPos(v.vertex);
53 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
54 UNITY_TRANSFER_FOG(o,o.vertex);
55 return o;
56 }
57
58 fixed4 frag (v2f i) : SV_Target
59 {
60 //取得整数的时间
61 float time = floor(_Time.y*_Speed);
62 //整除部分为行(因为播放顺序是从左到右,先行后列)
63 float row = floor(time / _CutX);
64 //余数部分为列
65 float column = time - row * _CutX;
66
67 //计算偏移值,其中u向为列索引值,v向为行索引的相反数(播放原点是左上角,而uv采样原点是左下角,所以v向偏移应该取反)
68 half2 uv = i.uv + half2(column,-row);
69 //除以行列得到最终的采样值
70 uv.x /= _CutX;
71 uv.y /= _CutY;
72
73 fixed4 col = tex2D(_MainTex,uv);
74 col.rgb *= _Color;
75 UNITY_APPLY_FOG(i.fogCoord, col);
76 return col;
77 }
78 ENDCG
79 }
80 }
81 FallBack "Transparent/VertexLit"
82 }