基于UGUI的卡牌效果Shader

2 篇文章 0 订阅
1 篇文章 0 订阅

废话不多说,先上效果图,因为博主美术水平有限,只做了很简单的扰动加流动。

此shader是基于UGUI上使用的shader,创建材质,拖到sprite的material上面即可。因为博主发现网上很多卡牌shader都是在面片等模型上面,如果一些不太懂shader的人来使用可能不会把他转换到UGUI的sprite上进行使用。那么我们先看下shader的属性图块:

可以看到,基本的都带有扰动效果,当然,如果你不需要可以不用放上扰动贴图和遮罩mask即可。

也就是说此shader最基本的是扰动效果,然后可以根据卡牌具体需求去添加不同的效果,shader里面设置了4层效果,当然效果开的越多,性能消耗越大,主要是对贴图的采样效果和贴图内存。

1,首先介绍下扰动效果图设置

如上图,扰动除了原有的基本贴图以外,首先需要一张扰动图(噪声图)做随机扰动,然后需要一张遮罩Mask图,遮罩Mask图来控制图片那部分可以有扰动,那部分没有扰动

从上图可以看到,白色代表可以扰动,黑色代表不能扰动。制作起来也非常简单。

2,新的层的效果

分别为特效效果图,移动方向图,效果颜色,移动速度,旋转速度,位置,锚点,大小,是否特效前景

根据名称基本都能理解可以做到的效果,可以去做某个方向的移动,或者旋转等。然后可以调整部分参数。

需要注意的是 Motion Texture 这张图的制作

透明通道部分为没有特效,然后采样这张图将RG通道作为特效贴图的UV来使用,并且在G通道使用_Time.x及速度相乘来控制移动。

后面另外3个效果层与此类似,可以根据卡牌效果进行添加。

3,代码

此Shader原理特别简单,大家可以根据美术需求进行调整,以下为源码:

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Hearthstone/Golden"
{
	Properties
	{
		_MainTex("Texture", 2D) = "black" {}
		_DistTex("Distortion Texture", 2D) = "grey" {}
		_DistMask("Distortion Mask", 2D) = "black" {}

		_EffectsLayer1Tex("", 2D) = "black"{}
		_EffectsLayer1Color("", Color) = (1,1,1,1)
		_EffectsLayer1Motion("", 2D) = "black"{}
		_EffectsLayer1MotionSpeed("", float) = 0 
		_EffectsLayer1Rotation("", float) = 0
		_EffectsLayer1PivotScale("", Vector) = (0.5,0.5,1,1)
		_EffectsLayer1Translation("", Vector) = (0,0,0,0)
		_EffectsLayer1Foreground("", float) = 0

		_EffectsLayer2Tex("", 2D) = "black"{}
		_EffectsLayer2Color("", Color) = (1,1,1,1)
		_EffectsLayer2Motion("", 2D) = "black"{}
		_EffectsLayer2MotionSpeed("", float) = 0
		_EffectsLayer2Rotation("", float) = 0
		_EffectsLayer2PivotScale("", Vector) = (0.5,0.5,1,1)
		_EffectsLayer2Translation("", Vector) = (0,0,0,0)
		_EffectsLayer2Foreground("", float) = 0

		_EffectsLayer3Tex("", 2D) = "black"{}
		_EffectsLayer3Color("", Color) = (1,1,1,1)
		_EffectsLayer3Motion("", 2D) = "black"{}
		_EffectsLayer3MotionSpeed("", float) = 0
		_EffectsLayer3Rotation("", float) = 0
		_EffectsLayer3PivotScale("", Vector) = (0.5,0.5,1,1)
		_EffectsLayer3Translation("", Vector) = (0,0,0,0)
		_EffectsLayer3Foreground("", float) = 0

		_EffectsLayer4Tex("", 2D) = "black"{}
		_EffectsLayer4Color("", Color) = (1,1,1,1)
		_EffectsLayer4Motion("", 2D) = "black"{}
		_EffectsLayer4MotionSpeed("", float) = 0
		_EffectsLayer4Rotation("", float) = 0
		_EffectsLayer4PivotScale("", Vector) = (0.5,0.5,1,1)
		_EffectsLayer4Translation("", Vector) = (0,0,0,0)
		_EffectsLayer4Foreground("", float) = 0

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

		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
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile __ UNITY_UI_CLIP_RECT
            #pragma multi_compile __ UNITY_UI_ALPHACLIP
			#pragma shader_feature EFFECTS_LAYER_1_OFF EFFECTS_LAYER_1_ON
			#pragma shader_feature EFFECTS_LAYER_2_OFF EFFECTS_LAYER_2_ON
			#pragma shader_feature EFFECTS_LAYER_3_OFF EFFECTS_LAYER_3_ON
			#pragma shader_feature EFFECTS_LAYER_4_OFF EFFECTS_LAYER_4_ON

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

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

			struct v2f
			{
				float4 vertex : SV_POSITION;
				float2 uv : TEXCOORD0;
				fixed4 color    : COLOR;
#if EFFECTS_LAYER_1_ON	
				float2 effect1uv : TEXCOORD1;
#endif
#if EFFECTS_LAYER_2_ON	
				float2 effect2uv : TEXCOORD2;
#endif
#if EFFECTS_LAYER_3_ON	
				float2 effect3uv : TEXCOORD3;
#endif
#if EFFECTS_LAYER_4_ON	
				float2 effect4uv : TEXCOORD4;
#endif

				float4 worldPosition : TEXCOORD5;
			};

			float4 _ClipRect;
			fixed4 _Color;
			sampler2D _MainTex;
			sampler2D _DistTex;
			sampler2D _DistMask;

			sampler2D _EffectsLayer1Tex;
			sampler2D _EffectsLayer1Motion;
			float _EffectsLayer1MotionSpeed;
			float _EffectsLayer1Rotation;
			float4 _EffectsLayer1PivotScale;
			half4 _EffectsLayer1Color;
			float _EffectsLayer1Foreground;
			float2 _EffectsLayer1Translation;

			sampler2D _EffectsLayer2Tex;
			sampler2D _EffectsLayer2Motion;
			float _EffectsLayer2MotionSpeed;
			float _EffectsLayer2Rotation;
			float4 _EffectsLayer2PivotScale;
			half4 _EffectsLayer2Color;
			float _EffectsLayer2Foreground;
			float2 _EffectsLayer2Translation;

			sampler2D _EffectsLayer3Tex;
			sampler2D _EffectsLayer3Motion;
			float _EffectsLayer3MotionSpeed;
			float _EffectsLayer3Rotation;
			float4 _EffectsLayer3PivotScale;
			half4 _EffectsLayer3Color;
			float _EffectsLayer3Foreground;
			float2 _EffectsLayer3Translation;

			sampler2D _EffectsLayer4Tex;
			sampler2D _EffectsLayer4Motion;
			float _EffectsLayer4MotionSpeed;
			float _EffectsLayer4Rotation;
			float4 _EffectsLayer4PivotScale;
			half4 _EffectsLayer4Color;
			float _EffectsLayer4Foreground;
			float2 _EffectsLayer4Translation;

			v2f vert(appdata v)
			{
				v2f o;
				o.worldPosition = v.vertex;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = v.uv;
				o.color = v.color * _Color;

				float2x2 rotationMatrix;
				float sinTheta;
				float cosTheta;

				// For each effect channel, calculate UV rotations and scale about the pivot, and translate the point.

#if EFFECTS_LAYER_1_ON		
				o.effect1uv = o.uv - _EffectsLayer1PivotScale.xy;
				sinTheta = sin(_EffectsLayer1Rotation * _Time);
				cosTheta = cos(_EffectsLayer1Rotation * _Time);
				rotationMatrix = float2x2(cosTheta, -sinTheta, sinTheta, cosTheta);
				o.effect1uv = (mul( (o.effect1uv - _EffectsLayer1Translation.xy) *
					(1 / _EffectsLayer1PivotScale.zw), rotationMatrix)
					+ _EffectsLayer1PivotScale.xy);
#endif

#if EFFECTS_LAYER_2_ON		
				o.effect2uv = o.uv - _EffectsLayer2PivotScale.xy;
				sinTheta = sin(_EffectsLayer2Rotation * _Time);
				cosTheta = cos(_EffectsLayer2Rotation * _Time);
				rotationMatrix = float2x2(cosTheta, -sinTheta, sinTheta, cosTheta);
				o.effect2uv = (mul((o.effect2uv - _EffectsLayer2Translation.xy) * (1 / _EffectsLayer2PivotScale.zw), rotationMatrix) + _EffectsLayer2PivotScale.xy);
#endif

#if EFFECTS_LAYER_3_ON		
				o.effect3uv = o.uv - _EffectsLayer3PivotScale.xy;
				sinTheta = sin(_EffectsLayer3Rotation * _Time);
				cosTheta = cos(_EffectsLayer3Rotation * _Time);
				rotationMatrix = float2x2(cosTheta, -sinTheta, sinTheta, cosTheta);
				o.effect3uv = (mul((o.effect3uv - _EffectsLayer3Translation.xy) * (1 / _EffectsLayer3PivotScale.zw), rotationMatrix) + _EffectsLayer3PivotScale.xy);
#endif

#if EFFECTS_LAYER_4_ON		
				o.effect4uv = o.uv - _EffectsLayer4PivotScale.xy;
				sinTheta = sin(_EffectsLayer4Rotation * _Time);
				cosTheta = cos(_EffectsLayer4Rotation * _Time);
				rotationMatrix = float2x2(cosTheta, -sinTheta, sinTheta, cosTheta);
				o.effect4uv = (mul((o.effect4uv - _EffectsLayer4Translation.xy) * (1 / _EffectsLayer4PivotScale.zw), rotationMatrix) + _EffectsLayer4PivotScale.xy);
#endif	
				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				float2 distScroll = float2(_Time.x, _Time.x);
				fixed2 dist = (tex2D(_DistTex, i.uv + distScroll).rg - 0.5) * 2;
				fixed distMask = tex2D(_DistMask, i.uv)[0];

				fixed4 col = tex2D(_MainTex, i.uv + dist * distMask * 0.025) * i.color;
				fixed bg = col.a;

#if EFFECTS_LAYER_1_ON		

				// Grab the motion texture, if the speed value is non-zero, we'll use the red and green channels as the UVs for the effect texture.
				// Else, we use the EffectUVs as is, but still keep the blue and alpha channels of the motion texture for later use (blending).

				fixed4 motion1 = tex2D(_EffectsLayer1Motion, i.uv);

				if (_EffectsLayer1MotionSpeed)
					motion1.y -= _Time.x * _EffectsLayer1MotionSpeed;
				else
					motion1 = fixed4(i.effect1uv.rg, motion1.b, motion1.a);

				fixed4 effect1 = tex2D(_EffectsLayer1Tex, motion1.xy) * motion1.a;
				effect1 *= _EffectsLayer1Color;

				// To the base color, we add the effect color, multiplied by it's own alpha, and then byu the back ground mask alpha (if this effect is not in the foreground).
				// TODO: Add support for alpha blending instead of additive, some cards seem to use that.

				col += effect1 * effect1.a * max(bg, _EffectsLayer1Foreground);
#endif

#if EFFECTS_LAYER_2_ON		

				fixed4 motion2 = tex2D(_EffectsLayer2Motion, i.uv);

				if (_EffectsLayer2MotionSpeed)
					motion2.y -= _Time.x * _EffectsLayer2MotionSpeed;
				else
					motion2 = fixed4(i.effect2uv.rg, motion2.b, motion2.a);

				fixed4 effect2 = tex2D(_EffectsLayer2Tex, motion2.rg) * motion2.a;
				effect2 *= _EffectsLayer2Color;

				col += effect2 * effect2.a * max(bg, _EffectsLayer2Foreground);
#endif

#if EFFECTS_LAYER_3_ON		

				fixed4 motion3 = tex2D(_EffectsLayer3Motion, i.uv);

				if (_EffectsLayer3MotionSpeed)
					motion3.y -= _Time.x * _EffectsLayer3MotionSpeed;
				else
					motion3 = fixed4(i.effect3uv.rg, motion3.b, motion3.a);

				fixed4 effect3 = tex2D(_EffectsLayer3Tex, motion3.rg) * motion3.a;
				effect3 *= _EffectsLayer3Color;

				col += effect3 * effect3.a * max(bg, _EffectsLayer3Foreground);
#endif

#if EFFECTS_LAYER_4_ON		

				fixed4 motion4 = tex2D(_EffectsLayer4Motion, i.uv);

				if (_EffectsLayer4MotionSpeed)
					motion4.y -= _Time.x * _EffectsLayer4MotionSpeed;
				else
					motion4 = fixed4(i.effect4uv.rg, motion4.b, motion4.a);

				fixed4 effect4 = tex2D(_EffectsLayer4Tex, motion4.rg) * motion4.a;
				effect4 *= _EffectsLayer4Color;

				col += effect4 * effect4.a * max(bg, _EffectsLayer4Foreground);
#endif

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

				#ifdef UNITY_UI_ALPHACLIP
                clip (col.a - 0.001);
                #endif
				return col;
		}
		ENDCG
	}
	}

	CustomEditor "GoldenMaterialEditor"
}

 

此shader已经在《克瑞因的纷争》游戏开发中使用,下图为游戏开发中图:

对游戏有兴趣的加QQ群:970747208

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冯海洋1121

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值