【Unity3d Shader】闪卡:UGUI的RawImage实现3D动画效果

游戏开发中常常会有精美的2D立绘,这种2D立绘一般为一张静态贴图,图片精美,但看地来比较呆板,不够生动形象。基于此问题,我们可以开发自己的shader实现动态效果。

如下图:左图为静态原始效果,右图为特殊渲染后的动态效果。(当然可以用Spine等其它方式做成动图,但在本文讨论范围)。

gif图片数据丢失比较严重:细看可以看到,妹子衣服的摆动,水面的波纹,妹子眼珠的转动,前景树枝的摇曳,树枝后面光束的转动,扇子上面宝石的闪烁,等动态效果。

 


实现原理为:给RawImage设置为自定义的材质(image_3d.shader),然后设置材质中的各个参数来实现动画。(Image3D.cs的作用也后面再介绍)

image_3d.shader,实现了多种动化效果,并利用遮罩图片的rgb通道和配置参数来做为动画的参数输入。

 

遮罩图片1(下左图)R:扇子上的光;G:水面;B:前景树枝

遮罩图片2(下右图)R:妹子的衣服;G:妹子的头发;B:妹子的眼睛

如果一张遮罩够用的话,最好只用一张遮罩会比较省。

遮罩中的颜色的值比如: 遮罩2中的红色,会有比较明显的颜色浓度过度(其它也有),用于控制衣服摆动的幅度,比如衣服的边缘处摆动幅度大,红色就比较深。

因为遮罩图层可能会有重叠。PS中遮罩层的图层要设置为“变亮“(如下图)。这样0XFF0000FF和0X009900FF混合后的颜色值会为0XFF9900FF,在shader中可以取到正确的值。PS图层中默认的”正常“在不同图层有重叠时会有最终颜色0XFF0000FF会把0X009900FF盖住,达不到我们要的效果。

然后在片元着色器中做动画

因为咱们要在材质球中编辑各个参数,所以用的是shader_feature而没用multi_compile

下面代码为简单示例:

fixed4 frag(v2f IN) : SV_Target
	{
		float2 mTexcoord = IN.texcoord;//原图的纹理坐标
		fixed3 mask = tex2D(_Mask, mTexcoord).rgb;//遮罩图
		mTexcoord += Wave(mTexcoord, _SpeedR, mask.r, _ParametersR);//用遮罩图的红色(mask.r)和其它参数(_SpeedR,_ParametersR )作为Wave函数的输入
		half4 color = (tex2D(_MainTex, mTexcoord) + _TextureSampleAdd);
		return color;
	}

 动画函数举例:波动

//params.x: 1,y方向的振幅
	//params.y: 1,y方向的频率
	//params.z: 1,x方向的振幅
	//params.w: 1,x方向的频率
	half2 Wave(float2 uv, float speed, float concentration, float4 params)
	{
		half2 offset;
		half2 phase = (uv + speed * half2(_Time.y, _Time.y))* PI * 2;
		offset.y = params.x * sin(params.y * phase.x);
		offset.x = params.z * sin(params.w * phase.y);
		offset = offset * concentration * 0.01;
		return offset;
	}

因为image_3d.shader代码比较多,并且组合方式不一定是最适合您的,所以只建议参考。

相关的资源:点击这里可以下载

以上动画中的实际代码如下:(可用代码)

// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)

Shader "mgo/image/image_3d"
{
	Properties
	{
		[PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
	_Color("Tint", Color) = (1,1,1,1)

		_StencilComp("Stencil Comparison", Float) = 8
		_Stencil("Stencil ID", Float) = 0
		_StencilOp("Stencil Operation", Float) = 0
		_StencilWriteMask("Stencil Write Mask", Float) = 255
		_StencilReadMask("Stencil Read Mask", Float) = 255

		_ColorMask("Color Mask", Float) = 15

		[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip("Use Alpha Clip", Float) = 0

		[Space(100)]
	[Header(The following is editable content for card)]
	[Toggle(_ENABLE_ANI)] _EnableAni("EnableAni", Int) = 0

		[NoScaleOffset]
	_Mask("Mask", 2D) = "white" {}
	//[KeywordEnum(Null, ThreeD, Wave, Flex, Move, Flash, Ripple, FlowLight, Spiral)] _Type_R("TypeR", Int) = 0
	[KeywordEnum(Null, ThreeD, Wave, Flex, Move, Flash, FlowLight, Ripple)] _Type_R("TypeR", Int) = 0
		_SpeedR("SpeedR", Range(-10,10)) = 1
		_ParametersR("ParametersR", vector) = (1,1,1,1)

		//[KeywordEnum(Null, Wave, Flex, Move, Flash, Ripple, FlowLight, Spiral)] _Type_G("TypeG", Int) = 0
		[KeywordEnum(Null, Wave, Flex, Move, Flash, FlowLight, Ripple)] _Type_G("TypeG", Int) = 0
		_SpeedG("SpeedG", Range(-10,10)) = 1
		_ParametersG("ParametersG", vector) = (1,1,1,1)

		//[KeywordEnum(Null, Wave, Flex, Move, Flash, Ripple, FlowLight, Spiral)] _Type_B("TypeB", Int) = 0
		[KeywordEnum(Null, Wave, Flex, Move, Flash, FlowLight, Ripple)] _Type_B("TypeB", Int) = 0
		_SpeedB("SpeedB", Range(-10,10)) = 1
		_ParametersB("ParametersB", vector) = (1,1,1,1)


		[NoScaleOffset]
	_Mask2("Mask2", 2D) = "white" {}
	//[KeywordEnum(Null, Wave, Flex, Move, Flash, Ripple, FlowLight, Spiral)] _Type2_R("Type2R", Int) = 0
	[KeywordEnum(Null, Wave, Flex, Move, Flash, FlowLight, Ripple)] _Type2_R("Type2R", Int) = 0
		_Speed2R("Speed2R", Range(-10,10)) = 1
		_Parameters2R("Parameters2R", vector) = (1,1,1,1)

		//[KeywordEnum(Null, Wave, Flex, Move, Flash, Ripple, FlowLight, Spiral)] _Type2_G("Type2G", Int) = 0
		[KeywordEnum(Null, Wave, Flex, Move, Flash, FlowLight, Ripple)] _Type2_G("Type2G", Int) = 0
		_Speed2G("Speed2G", Range(-10,10)) = 1
		_Parameters2G("Parameters2G", vector) = (1,1,1,1)

		//[KeywordEnum(Null, Wave, Flex, Move, Flash, Ripple, FlowLight, Spiral)] _Type2_B("Type2B", Int) = 0
		[KeywordEnum(Null, Wave, Flex, Move, Flash, FlowLight, Ripple)] _Type2_B("Type2B", Int) = 0
		_Speed2B("Speed2B", Range(-10,10)) = 1
		_Parameters2B("Parameters2B", vector) = (1,1,1,1)


		//--------------------------------------------
		[Space(100)]
	[Header(The following is editable content for effect)]
	[Header(Please do not check the effect options you do not use such as EnableFx1 EnableFx2 EnableFx3 EnableFx4)]
	[Toggle(_ENABLE_FX1)] _ENABLE_FX1("EnableFx1", Int) = 0
		[Toggle(_ENABLE_FX2)] _ENABLE_FX2("EnableFx2", Int) = 0
		[Toggle(_ENABLE_FX3)] _ENABLE_FX3("EnableFx3", Int) = 0
		[Toggle(_ENABLE_FX4)] _ENABLE_FX4("EnableFx4", Int) = 0

		[Header(effect 1 zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz)]
	_Fx1Tex("Fx1 Texture", 2D) = "white" {}
	[KeywordEnum(NULL, MASK_R, MASK_G, MASK_B, MASK2_R, MASK2_G, MASK2_B)] _Fx1("Fx1 Mask Color", Int) = 0
		[Toggle] _Fx1IsOneMinus("Fx1IsOneMinus", Int) = 0
		_Fx1SpeedMove("Fx1SpeedMove", Range(-10,10)) = 0
		_Fx1ParametersMove("Fx1ParametersMove", vector) = (1,1,1,1)
		_Fx1SpeedWave("Fx1SpeedWave", Range(-10,10)) = 0
		_Fx1ParametersWave("Fx1ParametersWave", vector) = (1,1,1,1)
		_Fx1SpeedFlex("Fx1SpeedFlex", Range(-10,10)) = 0
		_Fx1ParametersFlex("Fx1ParametersFlex", vector) = (1,1,1,1)
		_Fx1SpeedSpiral("Fx1SpeedSpiral", Range(-10,10)) = 0
		_Fx1ParametersSpiral("Fx1ParametersSpiral", vector) = (1,1,1,1)
		_Fx1SpeedFrameAni("Fx1SpeedFrameAni", Range(-10,10)) = 0
		_Fx1ParametersFrameAni("Fx1ParametersFrameAni", vector) = (1,1,1,1)
		_Fx1SpeedFlash("Fx1SpeedFlash", Range(-10,10)) = 0
		_Fx1ParametersFlash("Fx1ParametersFlash", vector) = (1,1,1,1)



		[Space(50)]
	[Header(effect 2 zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz)]

	_Fx2Tex("Fx2 Texture", 2D) = "white" {}
	[KeywordEnum(NULL, MASK_R, MASK_G, MASK_B, MASK2_R, MASK2_G, MASK2_B)] _Fx2("Fx2 Mask Color", Int) = 0
		[Toggle] _Fx2IsOneMinus("Fx2IsOneMinus", Int) = 0
		_Fx2SpeedMove("Fx2SpeedMove", Range(-10,10)) = 0
		_Fx2ParametersMove("Fx2ParametersMove", vector) = (1,1,1,1)
		_Fx2SpeedWave("Fx2SpeedWave", Range(-10,10)) = 0
		_Fx2ParametersWave("Fx2ParametersWave", vector) = (1,1,1,1)
		_Fx2SpeedFlex("Fx2SpeedFlex", Range(-10,10)) = 0
		_Fx2ParametersFlex("Fx2ParametersFlex", vector) = (1,1,1,1)
		_Fx2SpeedSpiral("Fx2SpeedSpiral", Range(-10,10)) = 0
		_Fx2ParametersSpiral("Fx2ParametersSpiral", vector) = (1,1,1,1)
		_Fx2SpeedFrameAni("Fx2SpeedFrameAni", Range(-10,10)) = 0
		_Fx2ParametersFrameAni("Fx2ParametersFrameAni", vector) = (1,1,1,1)
		_Fx2SpeedFlash("Fx2SpeedFlash", Range(-10,10)) = 0
		_Fx2ParametersFlash("Fx2ParametersFlash", vector) = (1,1,1,1)

		[Space(50)]
	[Header(effect 3 zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz)]

	_Fx3Tex("Fx3 Texture", 2D) = "white" {}
	[KeywordEnum(NULL, MASK_R, MASK_G, MASK_B, MASK2_R, MASK2_G, MASK2_B)] _Fx3("Fx3 Mask Color", Int) = 0
		[Toggle] _Fx3IsOneMinus("Fx3IsOneMinus", Int) = 0
		_Fx3SpeedMove("Fx3SpeedMove", Range(-10,10)) = 0
		_Fx3ParametersMove("Fx3ParametersMove", vector) = (1,1,1,1)
		_Fx3SpeedWave("Fx3SpeedWave", Range(-10,10)) = 0
		_Fx3ParametersWave("Fx3ParametersWave", vector) = (1,1,1,1)
		_Fx3SpeedFlex("Fx3SpeedFlex", Range(-10,10)) = 0
		_Fx3ParametersFlex("Fx3ParametersFlex", vector) = (1,1,1,1)
		_Fx3SpeedSpiral("Fx3SpeedSpiral", Range(-10, 10)) = 0
		_Fx3ParametersSpiral("Fx3ParametersSpiral", vector) = (1, 1, 1, 1)
		_Fx3SpeedFrameAni("Fx3SpeedFrameAni", Range(-10, 10)) = 0
		_Fx3ParametersFrameAni("Fx3ParametersFrameAni", vector) = (1, 1, 1, 1)
		_Fx3SpeedFlash("Fx3SpeedFlash", Range(-10,10)) = 0
		_Fx3ParametersFlash("Fx3ParametersFlash", vector) = (1,1,1,1)

		[Space(50)]
	[Header(effect 4 zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz)]

	_Fx4Tex("Fx4 Texture", 2D) = "white" {}
	[KeywordEnum(NULL, MASK_R, MASK_G, MASK_B, MASK2_R, MASK2_G, MASK2_B)] _Fx3("Fx4 Mask Color", Int) = 0
		[Toggle] _Fx4IsOneMinus("Fx4IsOneMinus", Int) = 0
		_Fx4SpeedMove("Fx4SpeedMove", Range(-10,10)) = 0
		_Fx4ParametersMove("Fx4ParametersMove", vector) = (1,1,1,1)
		_Fx4SpeedWave("Fx4SpeedWave", Range(-10,10)) = 0
		_Fx4ParametersWave("Fx4ParametersWave", vector) = (1,1,1,1)
		_Fx4SpeedFlex("Fx4SpeedFlex", Range(-10,10)) = 0
		_Fx4ParametersFlex("Fx4ParametersFlex", vector) = (1,1,1,1)
		_Fx4SpeedSpiral("Fx4SpeedSpiral", Range(-10, 10)) = 0
		_Fx4ParametersSpiral("Fx4ParametersSpiral", vector) = (1, 1, 1, 1)
		_Fx4SpeedFrameAni("Fx4SpeedFrameAni", Range(-10, 10)) = 0
		_Fx4ParametersFrameAni("Fx4ParametersFrameAni", vector) = (1, 1, 1, 1)
		_Fx4SpeedFlash("Fx4SpeedFlash", Range(-10,10)) = 0
		_Fx4ParametersFlash("Fx4ParametersFlash", vector) = (1,1,1,1)

	}

		SubShader
	{
		Tags
	{
		"Queue" = "Transparent"
		"IgnoreProjector" = "True"
		"RenderType" = "Transparent"
		"PreviewType" = "Plane"
		"CanUseSpriteAtlas" = "True"
	}

		Stencil
	{
		Ref[_Stencil]
		Comp[_StencilComp]
		Pass[_StencilOp]
		ReadMask[_StencilReadMask]
		WriteMask[_StencilWriteMask]
	}

		Cull Off
		Lighting Off
		ZWrite Off
		ZTest[unity_GUIZTestMode]
		Blend SrcAlpha OneMinusSrcAlpha
		ColorMask[_ColorMask]

		Pass
	{
		Name "Default"
		CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0

#include "UnityCG.cginc"
#include "UnityUI.cginc"

#pragma multi_compile __ UNITY_UI_CLIP_RECT
#pragma multi_compile __ UNITY_UI_ALPHACLIP

#pragma	shader_feature _ENABLE_ANI

		//#pragma	shader_feature _TYPE_R_NULL _TYPE_R_THREED _TYPE_R_WAVE _TYPE_R_FLEX _TYPE_R_MOVE _TYPE_R_FLASH _TYPE_R_RIPPLE _TYPE_R_FLOWLIGHT _TYPE_R_SPIRAL
		//#pragma	shader_feature _TYPE_G_NULL _TYPE_G_WAVE _TYPE_G_FLEX _TYPE_G_MOVE _TYPE_G_FLASH _TYPE_G_RIPPLE _TYPE_G_FLOWLIGHT _TYPE_G_SPIRAL
		//#pragma	shader_feature _TYPE_B_NULL _TYPE_B_WAVE _TYPE_B_FLEX _TYPE_B_MOVE _TYPE_B_FLASH _TYPE_B_RIPPLE _TYPE_B_FLOWLIGHT _TYPE_B_SPIRAL
		//#pragma	shader_feature _TYPE2_R_NULL _TYPE2_R_WAVE _TYPE2_R_FLEX _TYPE2_R_MOVE _TYPE2_R_FLASH _TYPE2_R_RIPPLE _TYPE2_R_FLOWLIGHT _TYPE2_R_SPIRAL
		//#pragma	shader_feature _TYPE2_G_NULL _TYPE2_G_WAVE _TYPE2_G_FLEX _TYPE2_G_MOVE _TYPE2_G_FLASH _TYPE2_G_RIPPLE _TYPE2_G_FLOWLIGHT _TYPE2_G_SPIRAL
		//#pragma	shader_feature _TYPE2_B_NULL _TYPE2_B_WAVE _TYPE2_B_FLEX _TYPE2_B_MOVE _TYPE2_B_FLASH _TYPE2_B_RIPPLE _TYPE2_B_FLOWLIGHT _TYPE2_B_SPIRAL

#pragma	shader_feature _TYPE_R_NULL _TYPE_R_WAVE _TYPE_R_FLEX _TYPE_R_MOVE _TYPE_R_FLASH _TYPE_R_FLOWLIGHT _TYPE_R_RIPPLE _TYPE_R_THREED
#pragma	shader_feature _TYPE_G_NULL _TYPE_G_WAVE _TYPE_G_FLEX _TYPE_G_MOVE _TYPE_G_FLASH _TYPE_G_FLOWLIGHT _TYPE_G_RIPPLE
#pragma	shader_feature _TYPE_B_NULL _TYPE_B_WAVE _TYPE_B_FLEX _TYPE_B_MOVE _TYPE_B_FLASH _TYPE_B_FLOWLIGHT _TYPE_B_RIPPLE
#pragma	shader_feature _TYPE2_R_NULL _TYPE2_R_WAVE _TYPE2_R_FLEX _TYPE2_R_MOVE _TYPE2_R_FLASH _TYPE2_R_FLOWLIGHT _TYPE2_R_RIPPLE
#pragma	shader_feature _TYPE2_G_NULL _TYPE2_G_WAVE _TYPE2_G_FLEX _TYPE2_G_MOVE _TYPE2_G_FLASH _TYPE2_G_FLOWLIGHT _TYPE2_G_RIPPLE
#pragma	shader_feature _TYPE2_B_NULL _TYPE2_B_WAVE _TYPE2_B_FLEX _TYPE2_B_MOVE _TYPE2_B_FLASH _TYPE2_B_FLOWLIGHT _TYPE2_B_RIPPLE

#pragma	shader_feature _ENABLE_FX1
#pragma	shader_feature _FX1_MASK_NULL _FX1_MASK_R _FX1_MASK_G _FX1_MASK_B _FX1_MASK2_R _FX1_MASK2_G _FX1_MASK2_B

#pragma	shader_feature _ENABLE_FX2
#pragma	shader_feature _FX2_MASK_NULL _FX2_MASK_R _FX2_MASK_G _FX2_MASK_B _FX2_MASK2_R _FX2_MASK2_G _FX2_MASK2_B

#pragma	shader_feature _ENABLE_FX3
#pragma	shader_feature _FX3_MASK_NULL _FX3_MASK_R _FX3_MASK_G _FX3_MASK_B _FX3_MASK2_R _FX3_MASK2_G _FX3_MASK2_B

#pragma	shader_feature _ENABLE_FX4
#pragma	shader_feature _FX4_MASK_NULL _FX4_MASK_R _FX4_MASK_G _FX4_MASK_B _FX4_MASK2_R _FX4_MASK2_G _FX4_MASK2_B


#define PI 3.1415926

		struct appdata_t
	{
		float4 vertex   : POSITION;
		float4 color    : COLOR;
		float2 texcoord : TEXCOORD0;
		UNITY_VERTEX_INPUT_INSTANCE_ID
	};

	struct v2f
	{
		float4 vertex   : SV_POSITION;
		fixed4 color : COLOR;
		float2 texcoord  : TEXCOORD0;
		float4 worldPosition : TEXCOORD1;
#if _ENABLE_FX1
		float2 fx1Texcoord  : TEXCOORD2;
#endif
#if _ENABLE_FX2
		float2 fx2Texcoord  : TEXCOORD3;
#endif
#if _ENABLE_FX3
		float2 fx3Texcoord  : TEXCOORD4;
#endif
#if _ENABLE_FX4
		float2 fx4Texcoord  : TEXCOORD5;
#endif
		UNITY_VERTEX_OUTPUT_STEREO
	};

	sampler2D _MainTex;
	fixed4 _Color;
	fixed4 _TextureSampleAdd;
	float4 _ClipRect;
	float4 _MainTex_ST;

	uniform sampler2D _Mask;
	uniform float4 _Mask_ST;
	uniform float _SpeedR;
	uniform float4 _ParametersR;
	uniform float _SpeedG;
	uniform float4 _ParametersG;
	uniform float _SpeedB;
	uniform float4 _ParametersB;

	uniform sampler2D _Mask2;
	uniform float4 _Mask2_ST;
	uniform float _Speed2R;
	uniform float4 _Parameters2R;
	uniform float _Speed2G;
	uniform float4 _Parameters2G;
	uniform float _Speed2B;
	uniform float4 _Parameters2B;


	uniform sampler2D _Fx1Tex;
	uniform float4 _Fx1Tex_ST;
	uniform bool _Fx1IsOneMinus;
	uniform float _Fx1SpeedMove;
	uniform float4 _Fx1ParametersMove;
	uniform float _Fx1SpeedWave;
	uniform float4 _Fx1ParametersWave;
	uniform float _Fx1SpeedFlex;
	uniform float4 _Fx1ParametersFlex;
	uniform float _Fx1SpeedSpiral;
	uniform float4 _Fx1ParametersSpiral;
	uniform float _Fx1SpeedFrameAni;
	uniform float4 _Fx1ParametersFrameAni;
	uniform float _Fx1SpeedFlash;
	uniform float4 _Fx1ParametersFlash;

	uniform sampler2D _Fx2Tex;
	uniform float4 _Fx2Tex_ST;
	uniform bool _Fx2IsOneMinus;
	uniform float _Fx2SpeedMove;
	uniform float4 _Fx2ParametersMove;
	uniform float _Fx2SpeedWave;
	uniform float4 _Fx2ParametersWave;
	uniform float _Fx2SpeedFlex;
	uniform float4 _Fx2ParametersFlex;
	uniform float _Fx2SpeedSpiral;
	uniform float4 _Fx2ParametersSpiral;
	uniform float _Fx2SpeedFrameAni;
	uniform float4 _Fx2ParametersFrameAni;
	uniform float _Fx2SpeedFlash;
	uniform float4 _Fx2ParametersFlash;

	uniform sampler2D _Fx3Tex;
	uniform float4 _Fx3Tex_ST;
	uniform bool _Fx3IsOneMinus;
	uniform float _Fx3SpeedMove;
	uniform float4 _Fx3ParametersMove;
	uniform float _Fx3SpeedWave;
	uniform float4 _Fx3ParametersWave;
	uniform float _Fx3SpeedFlex;
	uniform float4 _Fx3ParametersFlex;
	uniform float _Fx3SpeedSpiral;
	uniform float4 _Fx3ParametersSpiral;
	uniform float _Fx3SpeedFrameAni;
	uniform float4 _Fx3ParametersFrameAni;
	uniform float _Fx3SpeedFlash;
	uniform float4 _Fx3ParametersFlash;

	uniform sampler2D _Fx4Tex;
	uniform float4 _Fx4Tex_ST;
	uniform bool _Fx4IsOneMinus;
	uniform float _Fx4SpeedMove;
	uniform float4 _Fx4ParametersMove;
	uniform float _Fx4SpeedWave;
	uniform float4 _Fx4ParametersWave;
	uniform float _Fx4SpeedFlex;
	uniform float4 _Fx4ParametersFlex;
	uniform float _Fx4SpeedSpiral;
	uniform float4 _Fx4ParametersSpiral;
	uniform float _Fx4SpeedFrameAni;
	uniform float4 _Fx4ParametersFrameAni;
	uniform float _Fx4SpeedFlash;
	uniform float4 _Fx4ParametersFlash;


	//函数定义区

	//params.x: 自动情况下x方向移动的振幅
	//params.y: 大于0表示开启自动3d运动 小于等于0用于手动拖动操作。
	//params.z: 手动拖动操作时x方向的振幅
	//params.w: 手动拖动操作时y方向的振幅
	half2 ThreeD(float2 uv, float speed, float concentration, float4 params)
	{
		half2 offset;
		if (params.y > 0)
		{
			half2 phase = (speed * _Time.y) * PI * 2;
			offset.x = params.x * sin(phase);
			offset.y = 0;
		}
		else
		{
			offset.x = params.z;
			offset.y = params.w;
		}
		offset = offset * concentration * 0.01;
		return offset;
	}
	//params.x: 1,y方向的振幅
	//params.y: 1,y方向的频率
	//params.z: 1,x方向的振幅
	//params.w: 1,x方向的频率
	half2 Wave(float2 uv, float speed, float concentration, float4 params)
	{
		half2 offset;
		half2 phase = (uv + speed * half2(_Time.y, _Time.y))* PI * 2;
		offset.y = params.x * sin(params.y * phase.x);
		offset.x = params.z * sin(params.w * phase.y);
		offset = offset * concentration * 0.01;
		return offset;
	}

	//params.x: 1,x方向的振幅
	//params.y: 1,x方向的频率
	//params.z: 1,y方向的振幅
	//params.w: 1,y方向的频率
	half2 Flex(float2 uv, float speed, float concentration, float4 params)
	{
		half2 offset;
		half2 phase = (uv + speed * half2(_Time.y, _Time.y))* PI * 2;
		offset.x = params.x * sin(params.y * phase.x);
		offset.y = params.z * sin(params.w * phase.y);
		offset = offset * concentration * 0.01;
		return offset;
	}

	//params.x: 1,x方向的速度
	//params.y: 1,x方向的速度
	//params.z: 0,useless
	//params.w: 0,useless
	half2 Move(float2 uv, float speed, float concentration, float4 params)
	{
		half2 offset;
		half2 phase = speed * _Time.y;
		offset.x = phase * params.x % 1;
		offset.y = phase * params.y % 1;
		return offset;
	}
	//params.x: 1,red
	//params.y: 1,green
	//params.z: 1,blue
	//params.w: 0.2,最暗值
	half3 Flash(float2 uv, float speed, float concentration, float4 params)
	{
		half3 color;
		if (concentration > 0.01)
		{
			half2 phase = (speed * _Time.y) * PI * 2;
			half light = saturate(lerp(params.w, 1, (sin(phase) + 1) * 0.5))  * concentration;
			color = light * half3(params.x, params.y, params.z);
		}
		else
		{
			color = 0;
		}
		return color;
	}
	//params.x: 3,振幅
	//params.y: 9,频率
	//params.z: 0.5, 中心x
	//params.w: 0.5, 中心y
	half2 Ripple(float2 uv, float speed, float concentration, float4 params)
	{
		half dis = distance(float2(uv.x, uv.y * 1), params.zw);
		half2 offset = saturate(1 - dis) * params.x * sin((dis * params.y + _Time.y * speed) * 2 * PI);
		offset = offset * concentration * 0.01;
		return offset;
	}

	//params.x: 0,光柱旋转角度
	//params.y: 2,光柱频率(注意是否刷到目标位置)
	//params.z: 0.2,光柱宽度(0~1)表示百分比
	//params.w: 999900,光柱颜色(0~999999) red:990000 green:009900 blue:000099 yellow:999900 white:999999
	half3 Flowlight(float2 uv, float speed, float concentration, float4 params)
	{
		//sampler2D fxTex, 
		/*half2 offset;
		offset.y = 0;
		offset.x = (speed * _Time.y % 1 - 0.5) * params.x;
		half3 color = tex2D(fxTex, uv + offset);
		color = color * params.y * concentration;
		return color;*/

		half width = params.z;
		half rotation = params.x * PI / 180;
		half offset = (speed * _Time.y % 1 - 0.5) * params.y;
		float s, c;
		sincos(rotation, s, c);
		float2x2 rotMatrix = float2x2(c, -s, s, c);
		half2 fxUV = mul(uv, rotMatrix);

		half3 color = 0;
		if (fxUV.x > offset && fxUV.x < offset + width)
		{
			color = half3(params.w / 10000 % 100, params.w / 100 % 100, params.w % 100) * concentration * 0.05;
			fixed dis = abs(offset + width * 0.5 - fxUV.x);
			fixed featherWidth = 0.2;
			if (dis > width * (0.5 - featherWidth))
			{
				color *= lerp(1, 0, (dis - width * (0.5 - featherWidth)) / (width * featherWidth));
			}
		}

		return color;
	}

	//params.x: 0.5, 扭曲程度
	//params.y: 1,	 中心扭曲加速度
	//params.z: 0.5, 中心x
	//params.w: 0.5, 中心y
	half2 Spiral(float2 uv, float speed, float concentration, float4 params)
	{
		half dis = distance(uv.xy, params.zw);
		float rotation = params.x * pow(dis, -params.y);
		rotation += speed * _Time.y * 2 * PI;
		float s, c;
		sincos(rotation, s, c);
		float2x2 rotMatrix = float2x2(c, -s, s, c);
		half2 offset = mul(uv - params.zw, rotMatrix) + params.zw;
		return offset;
	}

	//params.x: 4, 水平x方向有几个元素
	//params.y: 4, 垂直y方向有几个元素
	//params.z: 0, useless
	//params.w: 0, useless
	half2 FrameAni(float2 uv, float speed, float concentration, float4 params)
	{
		half2 offset = uv / params.xy;
		fixed frame = floor(_Time.w * speed % (params.x * params.y));
		fixed2 step = 1 / params.xy;
		offset.x += (frame % params.x) * step.x;
		offset.y += (1 - floor(frame / params.x) * step.y - step.y);
		return offset;
	}

	v2f vert(appdata_t v)
	{
		v2f OUT;
		UNITY_SETUP_INSTANCE_ID(v);
		UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
		OUT.worldPosition = v.vertex;
		OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);

		OUT.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
#if _ENABLE_ANI
#if _ENABLE_FX1
		OUT.fx1Texcoord = TRANSFORM_TEX(v.texcoord, _Fx1Tex);
#endif
#if _ENABLE_FX2
		OUT.fx2Texcoord = TRANSFORM_TEX(v.texcoord, _Fx2Tex);
#endif
#if _ENABLE_FX3
		OUT.fx3Texcoord = TRANSFORM_TEX(v.texcoord, _Fx3Tex);
#endif
#if _ENABLE_FX4
		OUT.fx4Texcoord = TRANSFORM_TEX(v.texcoord, _Fx4Tex);
#endif
#endif


		OUT.color = v.color * _Color;
		return OUT;
	}

	fixed4 frag(v2f IN) : SV_Target
	{
#if _ENABLE_ANI
		fixed3 depth = tex2D(_Mask2, IN.texcoord).rgb;
	float2 mTexcoord = IN.texcoord;
	fixed4 mColor = IN.color;

	fixed3 mask = tex2D(_Mask, mTexcoord).rgb;
	fixed3 mask2 = tex2D(_Mask2, mTexcoord).rgb;
	//threeD------------------------------------------------------------------------------------------------------------------------------
#if _TYPE_R_THREED
	mTexcoord += ThreeD(mTexcoord, _SpeedR, mask.r, _ParametersR);
	mask2 = tex2D(_Mask2, mTexcoord).rgb;
#endif

	//wave------------------------------------------------------------------------------------------------------------------------------
#if _TYPE_R_WAVE
	mTexcoord += Wave(mTexcoord, _SpeedR, mask.r, _ParametersR);
	mask2 = tex2D(_Mask2, mTexcoord).rgb;
#endif
#if _TYPE_G_WAVE
	mTexcoord += Wave(mTexcoord, _SpeedG, mask.g, _ParametersG);
	mask2 = tex2D(_Mask2, mTexcoord).rgb;
#endif
#if _TYPE_B_WAVE
	mTexcoord += Wave(mTexcoord, _SpeedB, mask.b, _ParametersB);
	mask2 = tex2D(_Mask2, mTexcoord).rgb;
#endif
#if _TYPE2_R_WAVE
	mTexcoord += Wave(mTexcoord, _Speed2R, mask2.r, _Parameters2R);
#endif
#if _TYPE2_G_WAVE
	mTexcoord += Wave(mTexcoord, _Speed2G, mask2.g, _Parameters2G);
#endif
#if _TYPE2_B_WAVE
	mTexcoord += Wave(mTexcoord, _Speed2B, mask2.b, _Parameters2B);
#endif

	//flex------------------------------------------------------------------------------------------------------------------------------
#if _TYPE_R_FLEX
	mTexcoord += Flex(mTexcoord, _SpeedR, mask.r, _ParametersR);
	mask2 = tex2D(_Mask2, mTexcoord).rgb;
#endif
#if _TYPE_G_FLEX
	mTexcoord += Flex(mTexcoord, _SpeedG, mask.g, _ParametersG);
	mask2 = tex2D(_Mask2, mTexcoord).rgb;
#endif
#if _TYPE_B_FLEX
	mTexcoord += Flex(mTexcoord, _SpeedB, mask.b, _ParametersB);
	mask2 = tex2D(_Mask2, mTexcoord).rgb;
#endif
#if _TYPE2_R_FLEX
	mTexcoord += Flex(mTexcoord, _Speed2R, mask2.r, _Parameters2R);
#endif
#if _TYPE2_G_FLEX
	mTexcoord += Flex(mTexcoord, _Speed2G, mask2.g, _Parameters2G);
#endif
#if _TYPE2_B_FLEX
	mTexcoord += Flex(mTexcoord, _Speed2B, mask2.b, _Parameters2B);
#endif

	//move-----------------------------------------------------------------------------------------------------------------------------
#if _TYPE_R_MOVE
	mTexcoord += Move(mTexcoord, _SpeedR, mask.r, _ParametersR);
	mask2 = tex2D(_Mask2, mTexcoord).rgb;
#endif
#if _TYPE_G_MOVE
	mTexcoord += Move(mTexcoord, _SpeedG, mask.g, _ParametersG);
	mask2 = tex2D(_Mask2, mTexcoord).rgb;
#endif
#if _TYPE_B_MOVE
	mTexcoord += Move(mTexcoord, _SpeedB, mask.b, _ParametersB);
	mask2 = tex2D(_Mask2, mTexcoord).rgb;
#endif
#if _TYPE2_R_MOVE
	mTexcoord += Move(mTexcoord, _Speed2R, mask2.r, _Parameters2R);
#endif
#if _TYPE2_G_MOVE
	mTexcoord += Move(mTexcoord, _Speed2G, mask2.g, _Parameters2G);
#endif
#if _TYPE2_B_MOVE
	mTexcoord += Move(mTexcoord, _Speed2B, mask2.b, _Parameters2B);
#endif

	//flash-----------------------------------------------------------------------------------------------------------------------------
#if _TYPE_R_FLASH
	mColor.rgb += Flash(mTexcoord, _SpeedR, mask.r, _ParametersR);
#endif
#if _TYPE_G_FLASH
	mColor.rgb += Flash(mTexcoord, _SpeedG, mask.g, _ParametersG);
#endif
#if _TYPE_B_FLASH
	mColor.rgb += Flash(mTexcoord, _SpeedB, mask.b, _ParametersB);
#endif
#if _TYPE2_R_FLASH
	mColor.rgb += Flash(mTexcoord, _Speed2R, mask2.r, _Parameters2R);
#endif
#if _TYPE2_G_FLASH
	mColor.rgb += Flash(mTexcoord, _Speed2G, mask2.g, _Parameters2G);
#endif
#if _TYPE2_B_FLASH
	mColor.rgb += Flash(mTexcoord, _Speed2B, mask2.b, _Parameters2B);
#endif

	//ripple------------------------------------------------------------------------------------------------------------------------------
#if _TYPE_R_RIPPLE
	mTexcoord += Ripple(mTexcoord, _SpeedR, mask.r, _ParametersR);
	mask2 = tex2D(_Mask2, mTexcoord).rgb;
#endif
#if _TYPE_G_RIPPLE
	mTexcoord += Ripple(mTexcoord, _SpeedG, mask.g, _ParametersG);
	mask2 = tex2D(_Mask2, mTexcoord).rgb;
#endif
#if _TYPE_B_RIPPLE
	mTexcoord += Ripple(mTexcoord, _SpeedB, mask.b, _ParametersB);
	mask2 = tex2D(_Mask2, mTexcoord).rgb;
#endif
#if _TYPE2_R_RIPPLE
	mTexcoord += Ripple(mTexcoord, _Speed2R, mask2.r, _Parameters2R);
#endif
#if _TYPE2_G_RIPPLE
	mTexcoord += Ripple(mTexcoord, _Speed2G, mask2.g, _Parameters2G);
#endif
#if _TYPE2_B_RIPPLE
	mTexcoord += Ripple(mTexcoord, _Speed2B, mask2.b, _Parameters2B);
#endif

	//flowlight------------------------------------------------------------------------------------------------------------------------------
#if _TYPE_R_FLOWLIGHT
	mColor.rgb += Flowlight(mTexcoord, _SpeedR, mask.r, _ParametersR);
#endif
#if _TYPE_G_FLOWLIGHT
	mColor.rgb += Flowlight(mTexcoord, _SpeedG, mask.g, _ParametersG);
#endif
#if _TYPE_B_FLOWLIGHT
	mColor.rgb += Flowlight(mTexcoord, _SpeedB, mask.b, _ParametersB);
#endif
#if _TYPE2_R_FLOWLIGHT
	mColor.rgb += Flowlight(mTexcoord, _Speed2R, mask2.r, _Parameters2R);
#endif
#if _TYPE2_G_FLOWLIGHT
	mColor.rgb += Flowlight(mTexcoord, _Speed2G, mask2.g, _Parameters2G);
#endif
#if _TYPE2_B_FLOWLIGHT
	mColor.rgb += Flowlight(mTexcoord, _Speed2B, mask2.b, _Parameters2B);
#endif

	//
	spiral------------------------------------------------------------------------------------------------------------------------------
	//#if _TYPE_R_SPIRAL
	//				mTexcoord += Spiral(mTexcoord, _SpeedR, mask.r, _ParametersR);
	//#endif
	//#if _TYPE_G_SPIRAL
	//				mTexcoord += Spiral(mTexcoord, _SpeedG, mask.g, _ParametersG);
	//#endif
	//#if _TYPE_B_SPIRAL
	//				mTexcoord += Spiral(mTexcoord, _SpeedB, mask.b, _ParametersB);
	//#endif
	//#if _TYPE2_R_SPIRAL
	//				mTexcoord += Spiral(mTexcoord, _Speed2R, mask2.r, _Parameters2R);
	//#endif
	//#if _TYPE2_G_SPIRAL
	//				mTexcoord += Spiral(mTexcoord, _Speed2G, mask2.g, _Parameters2G);
	//#endif
	//#if _TYPE2_B_SPIRAL
	//				mTexcoord += Spiral(mTexcoord, _Speed2B, mask2.b, _Parameters2B);
	//#endif



#if _ENABLE_FX1 || _ENABLE_FX2 || _ENABLE_FX3 || _ENABLE_FX4
	float2 fxUV;
	fixed3 fxColor;
	float concentration;
#endif

#if _ENABLE_FX1_ENABLE_FX1 START
#if _FX1_MASK_R
	concentration = mask.r;
#elif _FX1_MASK_G
	concentration = mask.g;
#elif _FX1_MASK_B
	concentration = mask.b;
#elif _FX1_MASK2_R
	concentration = mask2.r;
#elif _FX1_MASK2_G
	concentration = mask2.g;
#elif _FX1_MASK2_B
	concentration = mask2.b;
#elif _FX1_MASK_NULL
	concentration = 1;
#endif

	if (_Fx1IsOneMinus)
	{
		concentration = 1 - concentration;
	}
	fxUV = IN.fx1Texcoord;
	if (_Fx1SpeedMove != 0.0)
	{
		fxUV += Move(fxUV, _Fx1SpeedMove, 1, _Fx1ParametersMove);
	}
	if (_Fx1SpeedWave != 0.0)
	{
		fxUV += Wave(fxUV, _Fx1SpeedWave, 1, _Fx1ParametersWave);
	}
	if (_Fx1SpeedFlex != 0.0)
	{
		fxUV += Flex(fxUV, _Fx1SpeedFlex, 1, _Fx1ParametersFlex);
	}
	if (_Fx1SpeedSpiral != 0.0)
	{
		fxUV = Spiral(fxUV, _Fx1SpeedSpiral, 1, _Fx1ParametersSpiral);
	}

	if (_Fx1SpeedFrameAni != 0.0)
	{
		fxUV = FrameAni(fxUV, _Fx1SpeedFrameAni, 1, _Fx1ParametersFrameAni);
	}



	fxColor = tex2D(_Fx1Tex, fxUV).rgb * concentration;
	if (_Fx1SpeedFlash != 0.0)
	{
		if (fxColor.r > 0.001 || fxColor.g > 0.001 || fxColor.b > 0.001)
		{
			fxColor.rgb *= Flash(fxUV, _Fx1SpeedFlash, 1, _Fx1ParametersFlash);
		}
	}
	mColor.rgb += fxColor;
#endif_ENABLE_FX1 END

#if _ENABLE_FX2_ENABLE_FX2 START
#if _FX2_MASK_R
	concentration = mask.r;
#elif _FX2_MASK_G
	concentration = mask.g;
#elif _FX2_MASK_B
	concentration = mask.b;
#elif _FX2_MASK2_R
	concentration = mask2.r;
#elif _FX2_MASK2_G
	concentration = mask2.g;
#elif _FX2_MASK2_B
	concentration = mask2.b;
#elif _FX2_MASK_NULL
	concentration = 1;
#endif
	if (_Fx2IsOneMinus)
	{
		concentration = 1 - concentration;
	}
	fxUV = IN.fx2Texcoord;
	if (_Fx2SpeedMove != 0.0)
	{
		fxUV += Move(fxUV, _Fx2SpeedMove, 1, _Fx2ParametersMove);
	}
	if (_Fx2SpeedWave != 0.0)
	{
		fxUV += Wave(fxUV, _Fx2SpeedWave, 1, _Fx2ParametersWave);
	}
	if (_Fx2SpeedFlex != 0.0)
	{
		fxUV += Flex(fxUV, _Fx2SpeedFlex, 1, _Fx2ParametersFlex);
	}
	if (_Fx2SpeedSpiral != 0.0)
	{
		fxUV = Spiral(fxUV, _Fx2SpeedSpiral, 1, _Fx2ParametersSpiral);
	}

	if (_Fx2SpeedFrameAni != 0.0)
	{
		fxUV = FrameAni(fxUV, _Fx2SpeedFrameAni, 1, _Fx2ParametersFrameAni);
	}


	fxColor = tex2D(_Fx2Tex, fxUV).rgb * concentration;

	if (_Fx2SpeedFlash != 0.0)
	{
		if (fxColor.r > 0.001 || fxColor.g > 0.001 || fxColor.b > 0.001)
		{
			fxColor.rgb *= Flash(fxUV, _Fx2SpeedFlash, 1, _Fx2ParametersFlash);
		}
	}

	mColor.rgb += fxColor;
#endif_ENABLE_FX2 END

#if _ENABLE_FX3_ENABLE_FX3 START
#if _FX3_MASK_R
	concentration = mask.r;
#elif _FX3_MASK_G
	concentration = mask.g;
#elif _FX3_MASK_B
	concentration = mask.b;
#elif _FX3_MASK2_R
	concentration = mask2.r;
#elif _FX3_MASK2_G
	concentration = mask2.g;
#elif _FX3_MASK2_B
	concentration = mask2.b;
#elif _FX3_MASK_NULL
	concentration = 1;
#endif
	if (_Fx3IsOneMinus)
	{
		concentration = 1 - concentration;
	}
	fxUV = IN.fx3Texcoord;
	if (_Fx3SpeedMove != 0.0)
	{
		fxUV += Move(fxUV, _Fx3SpeedMove, 1, _Fx3ParametersMove);
	}
	if (_Fx3SpeedWave != 0.0)
	{
		fxUV += Wave(fxUV, _Fx3SpeedWave, 1, _Fx3ParametersWave);
	}
	if (_Fx3SpeedFlex != 0.0)
	{
		fxUV += Flex(fxUV, _Fx3SpeedFlex, 1, _Fx3ParametersFlex);
	}
	if (_Fx3SpeedSpiral != 0.0)
	{
		fxUV = Spiral(fxUV, _Fx3SpeedSpiral, 1, _Fx3ParametersSpiral);
	}
	if (_Fx3SpeedFrameAni != 0.0)
	{
		fxUV = FrameAni(fxUV, _Fx3SpeedFrameAni, 1, _Fx3ParametersFrameAni);
	}

	fxColor = tex2D(_Fx3Tex, fxUV).rgb * concentration;


	if (_Fx3SpeedFlash != 0.0)
	{
		if (fxColor.r > 0.001 || fxColor.g > 0.001 || fxColor.b > 0.001)
		{
			fxColor.rgb *= Flash(fxUV, _Fx3SpeedFlash, 1, _Fx3ParametersFlash);
		}
	}
	mColor.rgb += fxColor;
#endif_ENABLE_FX3 END

#if _ENABLE_FX4_ENABLE_FX4 START
#if _FX4_MASK_R
	concentration = mask.r;
#elif _FX4_MASK_G
	concentration = mask.g;
#elif _FX4_MASK_B
	concentration = mask.b;
#elif _FX4_MASK2_R
	concentration = mask2.r;
#elif _FX4_MASK2_G
	concentration = mask2.g;
#elif _FX4_MASK2_B
	concentration = mask2.b;
#elif _FX4_MASK_NULL
	concentration = 1;
#endif
	if (_Fx4IsOneMinus)
	{
		concentration = 1 - concentration;
	}
	fxUV = IN.fx4Texcoord;
	if (_Fx4SpeedMove != 0.0)
	{
		fxUV += Move(fxUV, _Fx4SpeedMove, 1, _Fx4ParametersMove);
	}
	if (_Fx4SpeedWave != 0.0)
	{
		fxUV += Wave(fxUV, _Fx4SpeedWave, 1, _Fx4ParametersWave);
	}
	if (_Fx4SpeedFlex != 0.0)
	{
		fxUV += Flex(fxUV, _Fx4SpeedFlex, 1, _Fx4ParametersFlex);
	}
	if (_Fx4SpeedSpiral != 0.0)
	{
		fxUV = Spiral(fxUV, _Fx4SpeedSpiral, 1, _Fx4ParametersSpiral);
	}

	if (_Fx3SpeedFrameAni != 0.0)
	{
		fxUV = FrameAni(fxUV, _Fx4SpeedFrameAni, 1, _Fx4ParametersFrameAni);
	}


	fxColor = tex2D(_Fx4Tex, fxUV).rgb * concentration;

	if (_Fx4SpeedFlash != 0.0)
	{
		if (fxColor.r > 0.001 || fxColor.g > 0.001 || fxColor.b > 0.001)
		{
			fxColor.rgb *= Flash(fxUV, _Fx4SpeedFlash, 1, _Fx4ParametersFlash);
		}
	}

	mColor.rgb += fxColor;
#endif_ENABLE_FX4 END




	half4 color = (tex2D(_MainTex, mTexcoord) + _TextureSampleAdd) * mColor;

#else
		half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
#endif


#ifdef UNITY_UI_CLIP_RECT
		color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
#endif

#ifdef UNITY_UI_ALPHACLIP
		clip(color.a - 0.001);
#endif

		return color;
	}
		ENDCG
	}
	}
}

 

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值