欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

序列帧动画Shader

程序员文章站 2022-03-25 21:31:20
...

编写Shader将一张序列帧动画播放出来

效果图如下图所示

序列帧动画Shader

播放效果如下

序列帧动画Shader

原理:控制纹理UV。随时间改变X轴 Tiling,来显示单个火焰,再改变X轴的Offset来位移纹理切换其他火焰

Shader代码

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/UVAnim"
{
	Properties
	{
		_Color("Main Color", Color) = (1,1,1,1)
		_MainTex("Main Texture(RGB)", 2D) = "white" {}
		_TimePerFrame("TimePerFrame",float) = 150
	}
	
	SubShader
	{
		tags{"Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "True"}
		Blend SrcAlpha OneMinusSrcAlpha
		
		Pass
		{
			
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"
			
			float4 _Color;
			sampler2D _MainTex;
			float _TimePerFrame;
			
			struct v2f
			{
				float4 pos:POSITION;
				float2 uv:TEXCOORD0;
			};
			
			float2 moveUV(float2 vertUV)
			{
				//根据Texture纹理间隔来缩放纹理
				float textureNum = 12;
				//纹理UV切换速度
				//float timePerFrame = 150;
				//frac用于获取小数部分,_Time获取时间与timePerFrame乘积更加精细
				float index = frac(_Time.x / textureNum * _TimePerFrame);
				//缩放比例
				float2 uvScale = float2(1 / textureNum, 1);
				
				//切换纹理UV
				if(index <= uvScale.x)
					return vertUV * uvScale;
				else if(index <= 2 * uvScale.x)	
					return vertUV * uvScale + float2(uvScale.x, 0.0);
				else if(index <= 3 * uvScale.x)
					return vertUV * uvScale + float2(2 * uvScale.x, 0.0);
				else if(index <= 4 * uvScale.x)	
					return vertUV * uvScale + float2(3 * uvScale.x, 0.0);
				else if(index <= 5 * uvScale.x)
					return vertUV * uvScale + float2(4 * uvScale.x, 0.0);
				else if(index <= 6 * uvScale.x)
					return vertUV * uvScale + float2(5 * uvScale.x, 0.0);
				else if(index <= 7 * uvScale.x)	
					return vertUV * uvScale + float2(6 * uvScale.x, 0.0);
				else if(index <= 8 * uvScale.x)
					return vertUV * uvScale + float2(7 * uvScale.x, 0.0);
				else if(index <= 9 * uvScale.x)	
					return vertUV * uvScale + float2(8 * uvScale.x, 0.0);
				else if(index <= 10 * uvScale.x)
					return vertUV * uvScale + float2(9 * uvScale.x, 0.0);
				else if(index <= 11 * uvScale.x)
					return vertUV * uvScale + float2(10 * uvScale.x, 0.0);
				else
					return vertUV * uvScale + float2(11 * uvScale.x, 0.0);
			}
			
			v2f vert(appdata_base v)
			{
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.uv = moveUV(v.texcoord.xy);

				return o;
			}
			
			half4 frag(v2f i):COLOR
			{	
				half4 c = tex2D(_MainTex , i.uv) * _Color;
				return c;
			}
			
			ENDCG
		}
	}
}


最终效果如文中开篇所示!!

博客地址:blog.liujunliang.com.cn