123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- 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
- }
- }
- }
|