UnityShader 序列帧动画效果

实现原理:主要思想是设置显示uv纹理的大小,并逐帧修改图片的uv坐标。

实现步骤

1、我们首先用_Time.y和速度属性_Speed相乘得到模拟的时间。

2、然后我们用time除以_HorizontalAmount的结果值作为当前的行索引,除法结果的余数则是列索引。

3、接下来,我们根据行索引和列索引来构建真正的采样坐标。由于序列帧图像包含了很多张关键帧图像,这意味着采样坐标需要映射到关键帧图像的坐标范围。

4、我们可以把原纹理坐标i.uv按行数和列数进行等分,得到每个子图像的纹理坐标范围。

5、映射到对应的行列数后,再对纹理坐标进行偏移。

注意:Unity的纹理坐标竖直方向的顺序和序列帧纹理中竖直方向上的顺序是相反的。

 1 Shader "unilt/SceneRainSplash" {
 2     Properties {
 3         _MainTex ("Base (RGB)", 2D) = "white" {}               //序列帧动画纹理  
 4         _Color("Color Tint", Color) = (1, 1, 1, 1)            //颜色
 5         _HorizontalAmount("Horizontal Amount", float) = 6        // 行数
 6         _VerticalAmount("Vertical Amount", float) = 1            // 列数 
 7         _Speed("Speed", Range(1, 100)) = 7                     // 播放速度 
 8     }
 9     
10     CGINCLUDE
11 
12         #include "UnityCG.cginc"
13 
14         sampler2D _MainTex;
15         
16         uniform half4 _MainTex_ST;
17         uniform fixed4 _Color;
18         uniform float _HorizontalAmount;
19         uniform float _VerticalAmount;
20         uniform float _Speed;
21 
22         struct appdata
23         {
24             float4 vertex : POSITION;   //从形似寄存器中读取顶点坐标
25             float2 uv : TEXCOORD0;      //从形似寄存器中读取uv坐标信息
26         };
27         
28 
29         struct v2f
30         {
31             float2 uv : TEXCOORD0;
32             float4 vertex : SV_POSITION;
33         };
34 
35         v2f vert(appdata v)
36         {
37             v2f o;
38             
39             //mul(UNITY_MATRIX_MVP,*)' == 'UnityObjectToClipPos(*) 
40             //(物体的模型到世界矩阵 * 从世界到摄像机的矩阵 * 投影的矩阵 )
41             o.vertex = UnityObjectToClipPos(v.vertex);
42             
43             //TRANSFORM_TEX,就是将模型顶点的uv和Tiling、offset两个变量进行计算得出实际显示用的定点uv
44             o.uv = TRANSFORM_TEX(v.uv, _MainTex);
45             
46             return o; 
47         }
48         
49         fixed4 frag(v2f i) : SV_Target
50         {    
51             //所经过的时间,Unity内置变量_Timefloat4 _Time : Time (t/20, t, t*2, t*3)
52             float time = floor(_Time.y * _Speed);
53             //该时间渲染序列帧动画指定的行列
54             float row = floor(time / _HorizontalAmount);
55             float col = time - row * _HorizontalAmount;
56 
57             //将所显示的单张图片缩放到应有的大小区域
58             half2 uv = float2(i.uv.x / _HorizontalAmount, i.uv.y / _VerticalAmount);
59             //移动到对应缩放后的区域位置
60             uv.x += col / _HorizontalAmount;
61             uv.y -= row / _VerticalAmount;
62             fixed4 color = tex2D(_MainTex, uv);
63             color.rgb *= _Color.rgb;
64             return color;
65         }
66     
67     ENDCG
68     
69     SubShader {
70         Tags { "Queue" = "Transparent" }
71         Cull Off
72         ZWrite Off
73         Blend One OneMinusSrcColor
74 
75     Pass {
76     
77         CGPROGRAM
78         
79         #pragma vertex vert
80         #pragma fragment frag
81         #pragma fragmentoption ARB_precision_hint_fastest 
82         
83         ENDCG
84          
85         }
86                 
87     } 
88     FallBack Off
89 }

 

序列帧图像:

 

posted @ 2018-06-23 10:45  Mr. Ant  阅读(1920)  评论(0编辑  收藏  举报