参考链接: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