[UnityShader3]序列帧遮罩效果

参考链接:http://liweizhaolili.blog.163.com/blog/static/1623074420154412826120/


效果图:



上面的图有意思吧?呵呵。。其实就是使用序列帧加遮罩实现的,具体的可以看一下参考链接。


1.首先就是使用shader播放序列帧

Shader "Custom/Fire"
{
	Properties
	{
		_BottomTex ("BottomTex", 2D) = "white" {}
		_FrameTex ("FrameTex", 2D) = "white" {}

		_FrameRow ("FrameRow", Range(1, 5)) = 2
		_FrameColumn ("FrameColumn", Range(1, 5)) = 5
		_FrameSpeed ("FrameSpeed", Range(1, 10)) = 2
	}
	SubShader
	{
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float4 vertex : SV_POSITION;
				float2 uv : TEXCOORD0;
			};

			sampler2D _BottomTex;
			float4 _BottomTex_ST;
			sampler2D _FrameTex;
			float4 _FrameTex_ST;

			float _FrameRow;
			float _FrameColumn;
			float _FrameSpeed;

			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _FrameTex);

				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				//例如frame为7,则在一个两行五列的序列帧中
				//row为1,col为2(均以0开始计数)
				float frame = floor(_Time.y * _FrameSpeed);
				float row = floor(frame / _FrameRow);//当前播放的行数
				float col = frame - row * _FrameColumn;//当前播放的列数

				//先进行水平方向上的偏移,再进行竖直方向上的偏移
				//又因为纹理坐标y轴由下到上,而序列帧播放为由上到下,所以为负
				float2 uv = i.uv + float2(col, -row);
				//需要对uv进行等分缩放
				uv.x /= _FrameColumn;
				uv.y /= _FrameRow;

				fixed4 color = tex2D(_FrameTex, uv);
	
				return color;
			}
			ENDCG
		}
	}
}



2.将火焰和底图颜色叠加,并通过调整序列帧图的Offset属性将火焰定位到手的位置


Shader "Custom/Fire2"
{
	Properties
	{
		_BottomTex ("BottomTex", 2D) = "white" {}
		_FrameTex ("FrameTex", 2D) = "white" {}

		_FrameRow ("FrameRow", Range(1, 5)) = 2
		_FrameColumn ("FrameColumn", Range(1, 5)) = 5
		_FrameSpeed ("FrameSpeed", Range(1, 10)) = 2
	}
	SubShader
	{
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float4 vertex : SV_POSITION;
				float2 uv : TEXCOORD0;
				float2 uvFrame : TEXCOORD1;
			};

			sampler2D _BottomTex;
			float4 _BottomTex_ST;
			sampler2D _FrameTex;
			float4 _FrameTex_ST;

			float _FrameRow;
			float _FrameColumn;
			float _FrameSpeed;

			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _BottomTex);
				o.uvFrame = TRANSFORM_TEX(v.uv, _FrameTex);

				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				//例如frame为7,则在一个两行五列的序列帧中
				//row为1,col为2(均以0开始计数)
				float frame = floor(_Time.y * _FrameSpeed);
				float row = floor(frame / _FrameRow);//当前播放的行数
				float col = frame - row * _FrameColumn;//当前播放的列数

				//先进行水平方向上的偏移,再进行竖直方向上的偏移
				//又因为纹理坐标y轴由下到上,而序列帧播放为由上到下,所以为负
				float2 uv = i.uvFrame + float2(col, -row);
				//需要对uv进行等分缩放
				uv.x /= _FrameColumn;
				uv.y /= _FrameRow;

				fixed4 color = tex2D(_BottomTex, i.uv);
				fixed4 frameColor = tex2D(_FrameTex, uv);

				return color + frameColor;
			}
			ENDCG
		}
	}
}



3.此时你会发现火焰控制不了,下边和右边都冒出了,因此需要使用遮罩图去控制,过滤掉多余的火焰

Shader "Custom/Fire3"
{
	Properties
	{
		_BottomTex ("BottomTex", 2D) = "white" {}
		_FrameTex ("FrameTex", 2D) = "white" {}
		_MaskTex ("MaskTex", 2D) = "white" {}

		_FrameRow ("FrameRow", Range(1, 5)) = 2
		_FrameColumn ("FrameColumn", Range(1, 5)) = 5
		_FrameSpeed ("FrameSpeed", Range(1, 10)) = 2
	}
	SubShader
	{
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float4 vertex : SV_POSITION;
				float2 uv : TEXCOORD0;
				float2 uvFrame : TEXCOORD1;
			};

			sampler2D _BottomTex;
			float4 _BottomTex_ST;
			sampler2D _FrameTex;
			float4 _FrameTex_ST;
			sampler2D _MaskTex;
			float4 _MaskTex_ST;

			float _FrameRow;
			float _FrameColumn;
			float _FrameSpeed;

			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _BottomTex);
				o.uvFrame = TRANSFORM_TEX(v.uv, _FrameTex);

				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				//例如frame为7,则在一个两行五列的序列帧中
				//row为1,col为2(均以0开始计数)
				float frame = floor(_Time.y * _FrameSpeed);
				float row = floor(frame / _FrameRow);//当前播放的行数
				float col = frame - row * _FrameColumn;//当前播放的列数

				//先进行水平方向上的偏移,再进行竖直方向上的偏移
				//又因为纹理坐标y轴由下到上,而序列帧播放为由上到下,所以为负
				float2 uv = i.uvFrame + float2(col, -row);
				//需要对uv进行等分缩放
				uv.x /= _FrameColumn;
				uv.y /= _FrameRow;

				fixed4 color = tex2D(_BottomTex, i.uv);
				fixed4 frameColor = tex2D(_FrameTex, uv);
				fixed4 maskColor = tex2D(_MaskTex, i.uv);

				return color + frameColor * maskColor.b;
			}
			ENDCG
		}
	}
}


这是unitypackage:

http://pan.baidu.com/s/1qYKkMSk

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值