Unity Shader 从未入门到已放弃(十六)--中级 纹理动画

纹理动画 序列帧

在各种资源都比较局限的平台上,我们往往会使用纹理动画来代替复杂的粒子系统。

我们需要一张包含关键帧图像的图像。

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"
}

效果图:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值