1. 程式人生 > >Shader屏幕後處理效果

Shader屏幕後處理效果

Shader "MyShader/OutLine"
{
	Properties{
		_MainTex("MainTexture",2D) = "White"{}
		_LineColor("OutLineColor",color) = (1,1,1,1)
		_BackGroundColor("BackGroundColor",color) = (1,1,1,1)
		_EdgeOnly("EdgeOnly",float)=3
	}
		SubShader{
			Tags{"RenderType" = "Transparent"}
		Pass
		{
			Cull off
			ZTest Always
			ZWrite off
			CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
			sampler2D  _MainTex;
		float4 _MainTex_TexelSize;
		fixed4 _LineColor;
		fixed4 _BackGroundColor;
		float _EdgeOnly;
			struct a2v {
					fixed4 vertex : POSITION;
					fixed2 uv : TEXCOORD;
				};
			struct v2f {
				fixed4 pos : SV_POSITION;
				fixed2 uv[9]:TEXCOORD;//對應了使用Sobel運算元取樣是需要的
				//九個領域紋理座標
			};
			fixed luminance(fixed4 color)
			{
				return color.r*0.21 + color.g*0.37 + color.b*0.44;
			}
			half sobel(v2f v)  
			{
				const half Gx[9] = { 1,2,1,
					0,0,0,
					-1,-2,-1
				};
				const half Gy[9] = { 1,0,-1,
					2,0,-2,
					1,0,-1 };
				half texColor;
				half edgeX = 0;
				half edgeY = 0;
				for (int i = 0; i < 9; i++)
				{
					texColor = luminance(tex2D(_MainTex, v.uv[i])); 
					edgeX += texColor*Gx[i];
					edgeY += texColor*Gy[i];

				}
				return 1 - abs(edgeX) - abs(edgeY);
			}
			v2f vert(a2v v)
			{
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.uv[0] = v.uv + _MainTex_TexelSize.xy*fixed2(-1,1);
				o.uv[1] = v.uv + _MainTex_TexelSize.xy*fixed2(0, 1);
				o.uv[2] = v.uv + _MainTex_TexelSize.xy*fixed2(1, 1);
				o.uv[3] = v.uv + _MainTex_TexelSize.xy*fixed2(-1,0);
				o.uv[4] = v.uv + _MainTex_TexelSize.xy*fixed2(0, 0);
				o.uv[5] = v.uv + _MainTex_TexelSize.xy*fixed2(1, 0);
				o.uv[6] = v.uv + _MainTex_TexelSize.xy*fixed2(-1, -1);
				o.uv[7] = v.uv + _MainTex_TexelSize.xy*fixed2(0, -1);
				o.uv[8] = v.uv + _MainTex_TexelSize.xy*fixed2(1,-1);
				return o;
			}
			fixed4 frag(v2f v):SV_Target
			{
				half edge = sobel(v);  //計算梯度值edge
			fixed4 withEdgeColor = lerp(_LineColor, tex2D(_MainTex, v.uv[0]), edge);
			fixed4 onlyEdgeColor = lerp(_LineColor, _BackGroundColor,edge);
			
			return lerp(withEdgeColor, onlyEdgeColor, _EdgeOnly);
			}
	
			
			ENDCG
		}
	}
}