1. 程式人生 > >Unity Shader 實現描邊OutLine效果

Unity Shader 實現描邊OutLine效果

Shader實現描邊流程大致為:對模型進行2遍(2個pass)繪製,第一遍(描邊pass)在vertex shader中對模型沿頂點法線方向放大,fragment shader設定輸出顏色為描邊顏色;第二遍正常繪製模型,除被放大的部分外,其餘被覆蓋,這樣就有了描邊的效果。

實現程式碼如下:

Shader "Custom/OutlineShader" {
	Properties {
		_MainTex ("Albedo (RGB)", 2D) = "white" {}
		_OutLineWidth("width", float) = 1.2//定義一個變數
	}
	SubShader {

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

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

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


			float _OutLineWidth;//設定變數
			v2f vert(appdata v)
			{
				v2f o;
				//設定一下xy
				//v.vertex.xy *= 1.1;
				v.vertex.xy *= _OutLineWidth;//乘上變數
				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
				o.uv = v.uv;
				return o;
			}

			sampler2D _MainTex;

			fixed4 frag(v2f i) :SV_Target
			{
				fixed4 col = tex2D(_MainTex, i.uv);
				//return col;
				return fixed4(0, 0, 1, 1);
			}
			ENDCG
		}
		

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

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

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


			v2f vert(appdata v)
			{
				v2f o;
				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
				o.uv = v.uv;
				return o;
			}

			sampler2D _MainTex;

			fixed4 frag(v2f i) :SV_Target
			{
				fixed4 col = tex2D(_MainTex, i.uv);
				//return fixed4(0, 0, 1, 1);//返回藍色,因為再次渲染會把第一個顏色覆蓋掉
				return col;
			}
				ENDCG
			}
	} 
	FallBack "Diffuse"
}

物體被遮擋,仍然需要顯示,需要設定描邊pass的語句ZTest為Always,深度檢測一直通過,這樣描邊pass的片段不會被深度剔除。

執行效果圖: