纹理动画 序列帧
在各种资源都比较局限的平台上,我们往往会使用纹理动画来代替复杂的粒子系统。
我们需要一张包含关键帧图像的图像。
Shader "myShader/ImageSequenceAnimation"
{
Properties
{
_Color("Color Tint",Color) = (1,1,1,1)
_MainTex ("Main Tex", 2D) = "white" {} //包含了关键帧图像的纹理
_HorizontalAmount("Horizontal Amount", float) = 4 //水平方向关键帧图像个数
_VerticalAmount("Vertical Amount", float) = 4 //垂直方向关键帧图像个数
_Speed("Speed",Range(1,100)) = 30 //控制播放速度
}
SubShader
{
Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType"="Transparent" }//半透明标配标签
Pass
{
Tags{"LightMode" = "ForwardBase"}
//开启混合模式 关闭深度写入
ZWrite off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
float _HorizontalAmount;
float _VerticalAmount;
float _Speed;
struct a2v {
float4 vertex:POSITION;
float2 texcoord:TEXCOORD0;
};
struct v2f {
float4 pos:SV_POSITION;
float2 uv:TEXCOORD0;
};
v2f vert(a2v v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
fixed4 frag(v2f i) :SV_Target{
float time = floor(_Time.y * _Speed);//取得整数时间 _Time.y是自该场景加载后所经过的时间
float row = floor(time / _HorizontalAmount);
float column = time - row * _HorizontalAmount;
half2 uv = i.uv + half2(column, -row);
uv.x /= _HorizontalAmount;
uv.y /= _VerticalAmount;
fixed4 c = tex2D(_MainTex, uv);
c.rgb *= _Color;
return c;
}
ENDCG
}
}
FallBack "Transparent/VertexLit"
}
效果图:
背景滚动
Shader "myShader/ScrollingBackground"
{
Properties
{
_MainTex ("Main Tex", 2D) = "white" {} //第一层背景纹理
_DetailTex("2nd Layer(RGB)",2D) = "white"{} //第二层背景纹理
_ScrollX("Base Layer Scroll Speed", Float) = 1.0
_Scroll2X("2nd Layer Scroll Speed", Float) = 1.0
_Multiplier("Layer Multiplier",Float) = 1 //控制纹理的整体亮度
}
SubShader
{
Tags { "Queue" = "Geometry" "RenderType"="Opaque" }
Pass
{
Tags{"LightMode" = "ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _DetailTex;
float4 _DetailTex_ST;
float _ScrollX;
float _Scroll2X;
float _Multiplier;
struct a2v {
float4 vertex:POSITION;
float4 texcoord:TEXCOORD0;
};
struct v2f {
float4 pos:SV_POSITION;
float4 uv:TEXCOORD0;
};
v2f vert(a2v v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
//分别计算两层纹理的纹理坐标 TRANSFORM_TEX即可以得到初始坐标 利用_Time.y在水平方向上进行偏移
o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex) + frac(float2(_ScrollX, 0.0) * _Time.y);
o.uv.zw = TRANSFORM_TEX(v.texcoord, _DetailTex) + frac(float2(_Scroll2X, 0.0) * _Time.y);
return o;
}
fixed4 frag(v2f i) :SV_Target{
//对两张纹理进行采样
fixed4 firstLayer = tex2D(_MainTex, i.uv.xy);
fixed4 secondLayer = tex2D(_DetailTex, i.uv.zw);
//lerp(a, b, f) 计算(1−f)∗a+b∗f或者a+f∗(b−a)的值。即在下限a和上限b之间进行插值,f表示权值。注意,如果a和b是向量,则权值f必须是标量或者等长的向量。
fixed4 c = lerp(firstLayer, secondLayer, secondLayer.a);
c.rgb *= _Multiplier;
return c;
}
ENDCG
}
}
FallBack "VertexLit"
}
效果图: