Shader屏幕後處理效果
阿新 • • 發佈:2019-02-11
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 } } }