1. 程式人生 > >[UnityShader3]遮罩效果

[UnityShader3]遮罩效果

1.首先,就是不帶貼圖的遮罩效果了,很簡單,但是缺點也很明顯,就是uv會隨自適應而拉伸,造成鏤空區域發生變形,例如下圖,本想鏤空一個圓形區域,但是卻因為拉伸而變成橢圓了。


Shader "Custom/Mask"
{
	Properties
	{
	}
	SubShader
	{
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"

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

			struct v2f
			{			
				float4 vertex : SV_POSITION;
				float2 uv : TEXCOORD0;
			};
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
				o.uv = v.uv;

				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				float result = pow((i.uv.x - 0.5), 2) + pow((i.uv.y - 0.5), 2);
				if(result < pow(0.1, 2)) discard;

				return fixed4(0, 0, 0, 1);
			}
			ENDCG
		}
	}
}

2.因此,我們需要一張圓形區域的貼圖,如下圖。當然,如果直接對它進行取樣是不行的,圓形區域會覆蓋大半個螢幕,這裡需要設定貼圖的Wrap Mode為Clamp,表示當uv超出0~1範圍時取貼圖的邊緣顏色。並且,需要對它進行uv縮放與平移。



Shader "Custom/Mask2"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
	}
	SubShader
	{
		Tags { "Queue" = "AlphaTest" }

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

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

			struct v2f
			{			
				float4 vertex : SV_POSITION;
				float2 uv : TEXCOORD0;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				fixed4 col = tex2D(_MainTex, i.uv);
				clip(col.r - 0.7);

				return fixed4(0, 0, 0, 1);
			}
			ENDCG
		}
	}
}


3.上面的效果多用於遊戲中的"黑夜照明",而像新手指導那樣的,只需簡單修改,將黑色透明化即可。

Shader "Custom/Mask2"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
	}
	SubShader
	{
		Tags { "Queue" = "Transparent" }

		Pass
		{
			ZWrite off
			Blend SrcAlpha OneMinusSrcAlpha

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

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

			struct v2f
			{			
				float4 vertex : SV_POSITION;
				float2 uv : TEXCOORD0;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				fixed4 col = tex2D(_MainTex, i.uv);
				clip(col.r - 0.7);

				return fixed4(0, 0, 0, 0.7);
			}
			ENDCG
		}
	}
}

這是unitypackage:

http://pan.baidu.com/s/1o8kxkqI