您的位置:首页 > 移动开发 > Unity3D

UnityShader入门精要学习笔记(十六):纹理动画

2017-07-11 17:06 609 查看
一.简介

纹理动画在游戏中的应用非常广泛。尤其是在各种资源都比较局限的移动平台上,我们往往会使用纹理动画来代替复杂的粒子系统等模拟各种动画效果。

二.序列帧实现爆炸效果

1.思路

使用一个nXn的序列图,通过floor操作

每隔一段时间改变一次time,替换当前展示的单元图

计算uv时,先将顶点着色器中传入的uv映射到单元图的uv格子中

再将映射好的uv映射到正确行、列上

最后对纹理采样输出

2.代码实践

Shader "Custom/Edu/ImgSeqAnim" {
Properties {
_MainTex("Main Tex",2D) = "white"{}
_HAmount("HAmount",float) = 8
_VAmount("VAmount",float) = 8
_Speed("Speed",Range(1,100)) =30
_Color("Color Tint",Color) = (1,1,1,1)
}
SubShader {
Tags { "RenderType"="Opaque" }
Pass
{
Tags{"LightMode" = "ForwardBase"}

ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"

sampler2D _MainTex;
float4 _MainTex_ST;
half _HAmount;
half _VAmount;
half _Speed;
fixed4 _Color;

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 = mul(UNITY_MATRIX_MVP,v.vertex);
o.uv = v.texcoord;
return o;
}

fixed4 frag(v2f i):SV_Target
{
//这里要对时间取整!!!
//错误写法
//half time = _Time.y * _Speed;
//导致的后果是前后图片横向滑动而不是隔一段时间替换一次

half time = floor(_Time.y * _Speed);

half row = floor(time/_HAmount);

half column = time - row * _HAmount;

//将当前uv点映射到更小的单元序列图像上
half2 uv = half2(i.uv.x/_HAmount,i.uv.y/_VAmount);

//将当前uv映射到正确的序列图上
uv.x += column/_HAmount;
//Unity中纹理坐标的竖直方向上从下到上递增
//而序列帧纹理的播放顺序是从上到下的
uv.y -= row/_VAmount;

return tex2D(_MainTex,uv) * _Color;
}

ENDCG
}
}
FallBack "Diffuse"
}


3.效果图



三.滚动背景效果实现

1.基本思路

随着时间连续的横向改变采样的uv坐标,又结合前景与后景做不同的滚动速率以达到更加真实的背景效果。

2.代码实践

Shader "Custom/Edu/BgSroll" {
Properties {
_FrontTex("前景",2D) = "white"{}
_BackTex("后景",2D) = "white"{}
_ScrollSpeed1("前景滚动速度",Range(-10,10)) =1.0
_ScrollSpeed2("后景滚动速度",Range(-10,10)) =1.0
}
SubShader {
Tags { "RenderType"="BackGround" "Queue" = "BackGround"}
Pass
{
Tags{"LightMode" = "ForwardBase"}

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"

sampler2D _FrontTex;
float4 _FrontTex_ST;
sampler2D _BackTex;
float4 _BackTex_ST;
half _ScrollSpeed1;
half _ScrollSpeed2;

struct a2v
{
float4 vertex:POSITION;
float2 texcoord:TEXCOORD0;
};

struct v2f
{
float4 pos:SV_POSITION;
float4 uv:TEXCOORD0;
};

v2f vert(a2v v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP,v.vertex);

o.uv.xy = TRANSFORM_TEX(v.texcoord,_FrontTex);
//frac函数将会截获取得各个分量的小数部分
o.uv.xy += frac(float2(_ScrollSpeed1*_Time.y,0.0));

o.uv.zw = TRANSFORM_TEX(v.texcoord,_BackTex);
o.uv.zw += frac(float2(_ScrollSpeed2*_Time.y,0.0));

ab64
return o;
}

fixed4 frag(v2f i):SV_Target
{
fixed4 frontColor = tex2D(_FrontTex,i.uv.xy);
fixed4 backColor = tex2D(_BackTex,i.uv.zw);

return lerp(backColor,frontColor,frontColor.a);
}

ENDCG
}
}
FallBack "Diffuse"
}


3.效果图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: