unity 图片遮罩有锯齿_NGUI图片黑白滤镜效果

unity 图片遮罩有锯齿_NGUI图片黑白滤镜效果_第1张图片

最近在学习shader,正好UI需求一个黑白滤镜的效果,就试着做了一个demo。最初的设计是写一个mask图片遮罩的shader,让美术提供一张mask图片设置进去,但是策划想要的是一个跟章节关联的开启效果,每个章节的mask图片形状、位置、大小和数量都不一样,故放弃了这个想法。改为修改NGUIshader,开启zwrite,然后用遮挡的方式实现遮罩,大体思路参考了人物遮挡X光的实现方式(

https://blog.csdn.net/puppet_master/article/details/73478905​blog.csdn.net

)和NGUI新手指引制作(

NGUI利用深度测试实现新手引导遮罩 - Mr. Oy - 博客园​www.cnblogs.com
unity 图片遮罩有锯齿_NGUI图片黑白滤镜效果_第2张图片

),效果图如下:

unity 图片遮罩有锯齿_NGUI图片黑白滤镜效果_第3张图片

前期准备

1.修改NGUI的Transparent Colored shader,增加黑白图绘制并开启深度写入。

Shader "Unlit/Transparent Colored GrapyPass"
{
	Properties
	{
		_MainTex("Base (RGB), Alpha (A)", 2D) = "black" {}
	}
	SubShader
		{
			Tags
			{
				"Queue" = "Transparent+300"  //修改渲染队列,保证优先绘制
				"IgnoreProjector" = "True"
				"RenderType" = "Transparent"
			}

			//黑白颜色Pass
			Pass
			{
				ZWrite On            //开启深度写入
				ZTest Greater		 //修改深度测试条件						
				Offset -1, -1        //深度偏移(保证黑白色在最上边)
				Blend SrcAlpha OneMinusSrcAlpha

			CGPROGRAM
				#pragma vertex vert
				#pragma fragment frag			
				#include "UnityCG.cginc"

				sampler2D _MainTex;

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

				struct v2f
				{
					float4 vertex : SV_POSITION;
					half2 texcoord : TEXCOORD0;
				};

				v2f o;

				v2f vert(appdata_t v)
				{
					o.vertex = UnityObjectToClipPos(v.vertex);
					o.texcoord = v.texcoord;
					return o;
				}

				fixed4 frag(v2f IN) : COLOR
				{
					fixed4 MainTexcol = tex2D(_MainTex, IN.texcoord);
					fixed4 col = dot(MainTexcol.rgb, fixed3(.222, .707, .071));       //绘制黑白色图片
					col.a = MainTexcol.a;
					return col;
				}
			ENDCG
			}


			//正常颜色Pass
			Pass
			{
				ZWrite On
				Blend SrcAlpha OneMinusSrcAlpha
			CGPROGRAM
				#pragma vertex vert
				#pragma fragment frag			
				#include "UnityCG.cginc"

				sampler2D _MainTex;

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

				struct v2f
				{
					float4 vertex : SV_POSITION;
					half2 texcoord : TEXCOORD0;
					fixed4 color : COLOR;
				};

				v2f o;

				v2f vert(appdata_t v)
				{
					o.vertex = UnityObjectToClipPos(v.vertex);
					o.texcoord = v.texcoord;
					o.color = fixed4(v.color.rgb, v.color.a);
					return o;
				}

				fixed4 frag(v2f IN) : COLOR
				{
					return tex2D(_MainTex, IN.texcoord);
				}
			ENDCG
			}
		}
}

shader分为两个pass。第一个pass绘制黑白图片,深度测试条件Greater,也就会覆盖深度比它小的图片上边,配合后边说的mask图片就可以达到滤镜的效果。

以下是mask图集,白色部分代表要显示黑白图片,其余透明部分不显示:

unity 图片遮罩有锯齿_NGUI图片黑白滤镜效果_第4张图片

图集的shder:

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

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

Shader "Unlit/Texture(MaskGray) DephTest"
{
	Properties
	{
		 _CutOff("CutOff",Range(0,1)) = 0
		_MainTex("Base (RGB) Gray, Alpha (A)", 2D) = "white" {}
	}

	SubShader
	{
		LOD 200

		Tags
		{
			"Queue" = "Transparent"
			"IgnoreProjector" = "True"
			"RenderType" = "Transparent"
		}

		Pass
		{
			Cull Off
			Lighting Off
			ZWrite On           //开启深度缓存,以便做控件做基于深度的遮挡剔除
			Fog { Mode Off }
			Offset -1, -1
			ColorMask RGB        //不输出alpha通道

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma fragmentoption ARB_precision_hint_fastest

			#include "UnityCG.cginc"

			sampler2D _MainTex;
			fixed4 _Color;
			float _CutOff;
			struct appdata_t
			{
				float4 vertex : POSITION;
				fixed4 color : COLOR;
				float2 texcoord : TEXCOORD0;
			};

			struct v2f
			{
				float4 vertex : POSITION;
				fixed4 color : COLOR;
				float2 texcoord : TEXCOORD0;
				fixed gray : TEXCOORD1;
			};

			float4 _MainTex_ST;

			v2f vert(appdata_t v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.color = v.color;
				o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
				return o;
			}

			fixed4 frag(v2f i) : COLOR
			{
				fixed4 col;
				col = tex2D(_MainTex, i.texcoord) * i.color;
				clip(col.a - _CutOff);   //透明度测试
				return col;
			}
			ENDCG
		}
	}
}

其中clip(col.a - _CutOff)中的_CutOff=0.1,表示剪裁掉alpha<0.1的图片内容。

准备工作完成,然后我们创建UI来实现最终效果。

创建UI

unity 图片遮罩有锯齿_NGUI图片黑白滤镜效果_第5张图片

创建如上图的UI,其中Icon显示图片,图集shader是Transparent Colored GrapyPass,用来显示黑白色图片和彩色图片。

InfoPanel和BgPanel需要调整它们的Z值,保证BgPanel要在InfoPanel之前,好做遮挡。

unity 图片遮罩有锯齿_NGUI图片黑白滤镜效果_第6张图片

unity 图片遮罩有锯齿_NGUI图片黑白滤镜效果_第7张图片

因为BgPanel靠前,所以在渲染的时候会先绘制mask上的图片,又由于在mask图集上的shader开启了深度缓存,所以此时mask图片上白色部分的深度缓存是100。Icon上的图片由于开启了ZTest Greater,且深度是200,所以在渲染的时候深度测试通过,就会绘制出黑白图片,而其他地方就不会渲染了。效果如下:

unity 图片遮罩有锯齿_NGUI图片黑白滤镜效果_第8张图片

再正常渲染第二个pass就完成了最终效果。

unity 图片遮罩有锯齿_NGUI图片黑白滤镜效果_第9张图片

因为在黑白色pass中使用了Offset -1,-1,使得黑白色pass可以在彩色pass之上,否则黑白色会被彩色部分遮住。

实例地址:

https://github.com/l1000965431/NGUIShaderTest​github.com

你可能感兴趣的:(unity,图片遮罩有锯齿)