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

来源:互联网 发布:淘宝店铺名称怎么改 编辑:程序博客网 时间:2024/05/22 06:39

一.简介
纹理动画在游戏中的应用非常广泛。尤其是在各种资源都比较局限的移动平台上,我们往往会使用纹理动画来代替复杂的粒子系统等模拟各种动画效果。
二.序列帧实现爆炸效果
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));                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.效果图

阅读全文
0 0
原创粉丝点击