序列帧动画Shader

时间:2022-05-22 03:55:17

编写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