Shader "Custom/Convolution" { Properties { _MainTex ("Texture", 2D) = "white" {} [Enum(kerEdgeDetectionA,1,kerEdgeDetectionB,2,kerEdgeDetectionC,3,kerSharpen,4,kerBoxBlur,5)] _Kernel("Kernel", Float) = 1 } SubShader { // No culling or depth Cull Off ZWrite Off ZTest Always 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; }; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } sampler2D _MainTex; float4 _MainTex_TexelSize; float3x3 GetData(int channel, sampler2D tex, float2 uv, float4 size) { float3x3 mat; for (int y = -1; y < 2; y++) { for (int x = -1; x < 2; x++) { mat[x + 1][y + 1] = tex2D(tex, uv + float2(x * size.x, y * size.y))[channel]; } } return mat; } float3x3 GetMean(float3x3 matr, float3x3 matg, float3x3 matb) { float3x3 mat; for (int y = 0; y < 3; y++) { for (int x = 0; x < 3; x++) { mat[x][y] = (matr[x][y] + matg[x][y] + matb[x][y]) / 3.0; } } return mat; } float Convolve(float3x3 kernel, float3x3 pixels, float denom, float offset) { float res = 0.0; for (int y = 0; y < 3; y++) { for (int x = 0; x < 3; x++) { res += kernel[2 - x][2 - y] * pixels[x][y]; } } return res; } float _Kernel; fixed4 frag(v2f i) : SV_Target { float3x3 kerEdgeDetectionA = float3x3(0.0, 0, -1.0, 1.0, 0, -1.0, 0.0, 1.0, 0.0); float3x3 kerEdgeDetectionB = float3x3(0.0, 1.0, 0.0, 1.0, -4.0, 1.0, 0.0, 1.0, 0.0); float3x3 kerEdgeDetectionC = float3x3(-1.0, -1.0, -1.0, -1.0, 8.0, -1.0, -1.0, -1.0, -1.0); float3x3 kerSharpen = float3x3(0.0, -1.0, 0.0, -1.0, 5.0, -1.0, 0.0, -1.0, 0.0); float3x3 kerBoxBlur = (1.0 / 9.0) * float3x3(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0); float3x3 kernelSelection; if (_Kernel == 1) { kernelSelection = kerEdgeDetectionA; } else if (_Kernel == 2) { kernelSelection = kerEdgeDetectionB; } else if (_Kernel == 3) { kernelSelection = kerEdgeDetectionC; } else if (_Kernel == 4) { kernelSelection = kerSharpen; } else if (_Kernel == 5) { kernelSelection = kerBoxBlur; } float3x3 matr = GetData(0, _MainTex, i.uv, _MainTex_TexelSize); float3x3 matg = GetData(1, _MainTex, i.uv, _MainTex_TexelSize); float3x3 matb = GetData(2, _MainTex, i.uv, _MainTex_TexelSize); float3x3 mata = GetMean(matr, matg, matb); // kernel float4 gl_FragColor = float4(Convolve(kernelSelection, matr, 1.0, 0.0), Convolve(kernelSelection, matg, 1.0, 0.0), Convolve(kernelSelection, matb, 1.0, 0.0), 1.0); return gl_FragColor; } ENDCG } } }