Shader实现头像遮罩效果

发表于2017-08-22
评论0 657浏览
在Unity中有个Mask遮罩逐渐,使用这个组件也可以实现遮罩效果,这是在使用Unity自带的圆形图片时候效果如下:

可能是由于遮罩图片的像素问题导致的,大家可以尝试更换一张像素大点的遮罩图片,在这里就不试验了。

下面介绍另外一个方法,使用shader实现头像遮罩效果。

实现原理:
计算将圆形以外的顶点的Aphla透明图改为0

代码如下:
Shader "LJL/Cut" 
{
	Properties 
	{
		_Radius("_Radius",Range(0,1.2))=0.5
		_MainTex("_MainTex",2D)="white"{}
	}
	SubShader 
	{
		Tags{ "Queue"="Transparent" "IngnoreProjector"="True" "RenderType"="Transparent" }
		Pass 
		{
			Tags{ "LightMode" = "ForwardBase" }
			//必须加入才能实现透明效果
			ZWrite Off
			Blend SrcAlpha OneMinusSrcAlpha
			CGPROGRAM
			#include "UnityCG.cginc"
			#include "Lighting.cginc"  
			#pragma vertex vert
			#pragma fragment frag
			sampler2D _MainTex;
			fixed4 _MainTex_ST;
			float _Radius;
			struct a2v
			{
				float4 position:POSITION ;
				float4 texcoord:TEXCOORD0 ; 
			};
			struct v2f
			{
				float4 position:SV_POSITION ;
				float2 texcoord:TEXCOORD0 ; 
			};
			v2f vert(a2v v)
			{
				v2f f;
				f.position=mul(UNITY_MATRIX_MVP,v.position) ;
				//获取该顶点下的纹理坐标
				f.texcoord=v.texcoord.xy*_MainTex_ST.xy+_MainTex_ST.zw;
				return f;
			}
			fixed4 frag(v2f f):SV_Target
			{
				//获取纹理坐标下的颜色值
				fixed4 color = tex2D(_MainTex,f.texcoord);
				//左上方区域
				if(f.texcoord.x<0.5 && f.texcoord.y>0.5)
				{
					float2 r;
					r.x=0.5-f.texcoord.x;
					r.y=f.texcoord.y-0.5;
					if(length(r)>_Radius)//以r.x、r.y为两直角边长度,计算斜边长度
					{
						return fixed4(1,1,1,0);
					}
					else
					{
						return color;
					}
				}
				//左下方区域
				else if(f.texcoord.x<0.5 && f.texcoord.y<0.5)
				{
					float2 r;
					r.x=0.5-f.texcoord.x;
					r.y=0.5-f.texcoord.y;
					if(length(r)>_Radius)
					{
						return fixed4(1,1,1,0);
					}
					else
					{
						return color;
					}
				}
				//右上方区域
				else if(f.texcoord.x>0.5 && f.texcoord.y>0.5)
				{
					float2 r;
					r.x=f.texcoord.x-0.5;
					r.y=f.texcoord.y-0.5;
					if(length(r)>_Radius)
					{
						return fixed4(1,1,1,0);
					}
					else
					{
						return color;
					}
				}
				//右下方区域
				else if(f.texcoord.x>0.5 && f.texcoord.y<0.5)
				{
					float2 r;
					r.x=f.texcoord.x-0.5;
					r.y=0.5-f.texcoord.y;
					if(length(r)>_Radius)
					{
						return fixed4(1,1,1,0);
					}
					else
					{
						return color;
					}
				}
				return color;
			}
			ENDCG
		}
	}
	Fallback "Diffuse"
}

改变_Ridius的值,效果图如下:

发现效果显着比使用Mask组件要好很多

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

标签:

0个评论