unity 特效shader下载_UI流光特效穿透问题

1ba4d67fae52d464d2a2cf197a5fe7cc.png

手头一个项目在做UI流光特效的时候发现一个很普遍的问题:特效穿透

之前的项目中,虽然也有类似特效。但是特效所在的页面不会被遮住,或者有新页面时特效所在的页面会被隐藏,所以可以忽略不计。

这次的特效稍有不同,特效所在的页面是最底层ui,始终存在且不做隐藏,所以之前的缩小或者置顶的方式便无法使用了。

为了解决这个问题,我网上查阅了一下,找到了几种解决方法:

1.改被穿透UI的层级

2.降低特效层级

3.新页面用新摄像头

4.出现高层UI时隐藏特效

改被穿透UI的层级

修改被穿透的UI层级(renderer queue、order in layer等)可以解决这个问题,但同时也带来了另一个问题。就是所有渲染层级高于该特效的UI都需要添加一个UI材质去提高渲染层级,否则要么被穿透,要么被已经提高了层级的其他UI所遮挡。

降低特效层级

这个不可取,因为特效的渲染层级一旦改低,哪怕只是-1,就会被底部UI所遮挡。那么我们要做的就是将包括特效在内的所有应该低于特效的UI的渲染层级都一起降低,才不会出现特效被底层UI遮挡的情况。

新页面用新摄像头。

这个可以解决问题且比上面两个方便多了,但新页面用新摄像头总有一种大炮打蚊子的感觉,所以也,没使用这个方法。

出现高层UI时隐藏特效

这个方法就见仁见智了,方法的问题主要有两个

  1. 需要监听所有页面生成和移除,然后判断和当前页面的关系,然后再去控制特效显示与否。
  2. 如果上面的页面是个带半透明遮罩的弹窗,那么是可以通过半透明遮罩看到特效的突然关闭与显示的,看起来怪怪的。

上面的4个解决方案就是我大致找到的,应该还有更好的方案,但我确实没找到。

我想了一下后,发现这个流光本身并不复杂,应该可以通过 UI图片 做偏移来模拟这个效果。

创建了一个材质并改为UI-Default之后发现偏移所用的Offset参数并未开方,所以我根据之前看的相关教程对UI-Default做了一些修改。

Shader "UI/Default-Offset"
{
	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

		_HorizontalAmount ("Horizontal Amount", Float) = 4  //新增变量
    	        _VerticalAmount ("Vertical Amount", Float) = 4   //新增变量
    	        _Speed ("Speed", Range(1, 100)) = 30   //新增变量
     
		[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
		{
			Name "Default"
		CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma target 2.0

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

			#pragma multi_compile __ UNITY_UI_ALPHACLIP
			
			struct appdata_t
			{
				float4 vertex   : POSITION;
				float4 color    : COLOR;
				float2 texcoord : TEXCOORD0;
			};

			struct v2f
			{
				float4 vertex   : SV_POSITION;
				fixed4 color    : COLOR;
				half2 texcoord  : TEXCOORD0;
				float4 worldPosition : TEXCOORD1;
			};
			
			fixed4 _Color;
			fixed4 _TextureSampleAdd;
			float4 _ClipRect;

			v2f vert(appdata_t IN)
			{
				v2f OUT;
				OUT.worldPosition = IN.vertex;
				OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);

				OUT.texcoord = IN.texcoord;
				
				#ifdef UNITY_HALF_TEXEL_OFFSET
				OUT.vertex.xy += (_ScreenParams.zw-1.0) * float2(-1,1) * OUT.vertex.w;
				#endif
				
				OUT.color = IN.color * _Color;
				return OUT;
			}

			sampler2D _MainTex;
			float4 _MainTex_ST;

			float _HorizontalAmount;  //引用
			float _VerticalAmount;  //引用
			float _Speed;  //引用

			fixed4 frag(v2f IN) : SV_Target
			{
				//======修改的内容=========
				float time = floor(_Time.y * _Speed);  
				float row = floor(time / _HorizontalAmount);
				float column = time - row * _HorizontalAmount;
				
				half2 uv = IN.texcoord + half2(column, -row);
				uv.x /=  _HorizontalAmount;
				uv.y /= _VerticalAmount;
				
				half4 color = (tex2D(_MainTex, uv) + _TextureSampleAdd) * IN.color;
				//===================



				color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
				
				#ifdef UNITY_UI_ALPHACLIP
				clip (color.a - 0.001);
				#endif

				return color;
			}
		ENDCG
		}
	}
}
  1. 将该shader设置为ui材质的shader,路径为“UI/Default-Offset”
  2. HorizontalAmount 控制水平移速,1为静止(建议每次增加0.01
  3. VerticalAmount 控制垂直移速,1为静止(建议每次增加0.01
  4. Speed 控制流光速度

c15c9ccf9f0200158b75bfc8c6e7beb6.png
建议参数值

原理是通过时间变化来自动控制采样偏移来模拟流光效果,图片建议两侧不要有被裁切的流光,最高能左右接的上去。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值