Unity shader学习之屏幕后期处理效果之边缘检测
边缘检测的原理是利用一些边缘检测算子对图像进行卷积操作。
转载请注明出处:http://www.cnblogs.com/jietian331/p/7232707.html
例如:
代码如下:
1 using UnityEngine; 2 3 public class EdgeDetectRenderer : PostEffectRenderer 4 { 5 [SerializeField] 6 Color m_edgeColor; 7 8 protected override void OnRenderImage(RenderTexture src, RenderTexture dest) 9 { 10 base.Mat.SetColor("_EdgeColor", m_edgeColor); 11 base.OnRenderImage(src, dest); 12 } 13 14 protected override string ShaderName 15 { 16 get { return "Custom/Edge Detect"; } 17 } 18 }
shader如下:
1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' 2 3 Shader "Custom/Edge Detect" 4 { 5 Properties 6 { 7 _MainTex("Main Texture", 2D) = "white" {} 8 _EdgeColor("Edge Color", Color) = (1,1,1,1) 9 } 10 11 SubShader 12 { 13 Pass 14 { 15 Cull Off 16 ZWrite Off 17 ZTest Always 18 19 CGPROGRAM 20 #pragma vertex vert 21 #pragma fragment frag 22 23 sampler2D _MainTex; 24 float4 _MainTex_TexelSize; 25 uniform fixed4 _EdgeColor; 26 27 struct appdata 28 { 29 float4 vertex : POSITION; 30 float2 uv : TEXCOORD0; 31 }; 32 33 struct v2f 34 { 35 float4 pos : SV_POSITION; 36 half2 uv[9] : TEXCOORD0; 37 }; 38 39 v2f vert(appdata v) 40 { 41 v2f o; 42 o.pos = UnityObjectToClipPos(v.vertex); 43 o.uv[0] = v.uv + _MainTex_TexelSize.xy * half2(-1, 1); 44 o.uv[1] = v.uv + _MainTex_TexelSize.xy * half2(0, 1); 45 o.uv[2] = v.uv + _MainTex_TexelSize.xy * half2(1, 1); 46 o.uv[3] = v.uv + _MainTex_TexelSize.xy * half2(-1, 0); 47 o.uv[4] = v.uv + _MainTex_TexelSize.xy * half2(0, 0); 48 o.uv[5] = v.uv + _MainTex_TexelSize.xy * half2(1, 0); 49 o.uv[6] = v.uv + _MainTex_TexelSize.xy * half2(-1, -1); 50 o.uv[7] = v.uv + _MainTex_TexelSize.xy * half2(0, -1); 51 o.uv[8] = v.uv + _MainTex_TexelSize.xy * half2(1, -1); 52 return o; 53 } 54 55 float luminance(float3 color) 56 { 57 return dot(fixed3(0.2125, 0.7154, 0.0721), color); 58 } 59 60 half sober(half2 uvs[9]) 61 { 62 half gx[9] = { -1, 0, 1, 63 -2, 0, 2, 64 -1, 0, 1}; 65 half gy[9] = { -1, -2, -1, 66 0, 0, 0, 67 1, 2, 1}; 68 69 float edgeX = 0; 70 float edgeY = 0; 71 72 for(int i = 0; i < 9; i++) 73 { 74 fixed3 c = tex2D(_MainTex, uvs[i]).rgb; 75 float l = luminance(c); 76 edgeX += l * gx[i]; 77 edgeY += l * gy[i]; 78 } 79 80 return abs(edgeX) + abs(edgeY); 81 } 82 83 fixed4 frag(v2f i) : SV_TARGET 84 { 85 half edge = sober(i.uv); 86 fixed4 tex = tex2D(_MainTex, i.uv[4]); 87 return lerp(tex, _EdgeColor, edge); 88 } 89 90 ENDCG 91 } 92 } 93 94 Fallback Off 95 }
效果如下: