1
2 Shader
"Hidden/EdgeDetect" {
3     Properties {
4         _MainTex (
"Base (RGB)", 2D) = "" {}
5     }
6
7     CGINCLUDE
8     
9     #include
"UnityCG.cginc"
10     
11     
struct v2f {
12         float4 pos : SV_POSITION;
13         float2 uv[
5] : TEXCOORD0;
14     };
15     
16     
struct v2fd {
17         float4 pos : SV_POSITION;
18         float2 uv[
2] : TEXCOORD0;
19     };
20
21     sampler2D _MainTex;
22     uniform float4 _MainTex_TexelSize;
23
24     sampler2D _CameraDepthNormalsTexture;
25     sampler2D_float _CameraDepthTexture;
26
27     uniform half4 _Sensitivity;
28     uniform half4 _BgColor;
29     uniform half _BgFade;
30     uniform half _SampleDistance;
31     uniform
float _Exponent;
32
33     uniform
float _Threshold;
34
35     
struct v2flum {
36         float4 pos : SV_POSITION;
37         float2 uv[
3] : TEXCOORD0;
38     };
39
40     v2flum vertLum (appdata_img v)
41     {
42         v2flum o;
43         o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
44         float2 uv = MultiplyUV( UNITY_MATRIX_TEXTURE0, v.texcoord );
45         o.uv[
0] = uv;
46         o.uv[
1] = uv + float2(-_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance;
47         o.uv[
2] = uv + float2(+_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance;
48         
return o;
49     }
50
51
52     fixed4 fragLum (v2flum i) : SV_Target
53     {
54         fixed4 original = tex2D(_MainTex, i.uv[
0]);
55
56         
// a very simple cross gradient filter
57
58         half3 p1 = original.rgb;
59         half3 p2 = tex2D(_MainTex, i.uv[
1]).rgb;
60         half3 p3 = tex2D(_MainTex, i.uv[
2]).rgb;
61         
62         half3 diff = p1 *
2 - p2 - p3;
63         half len = dot(diff, diff);
64         len = step(len, _Threshold);
65         
//if(len >= _Threshold)
66         
// original.rgb = 0;
67
68         
return len * lerp(original, _BgColor, _BgFade);
69     }
70     
71     inline half CheckSame (half2 centerNormal,
float centerDepth, half4 theSample)
72     {
73         
// difference in normals
74         
// do not bother decoding normals - there's no need here
75         half2 diff = abs(centerNormal - theSample.xy) * _Sensitivity.y;
76         half isSameNormal = (diff.x + diff.y) * _Sensitivity.y <
0.1;
77         
// difference in depth
78         
float sampleDepth = DecodeFloatRG (theSample.zw);
79         
float zdiff = abs(centerDepth-sampleDepth);
80         
// scale the required threshold by the distance
81         half isSameDepth = zdiff * _Sensitivity.x <
0.09 * centerDepth;
82     
83         
// return:
84         
// 1 - if normals and depth are similar enough
85         
// 0 - otherwise
86         
87         
return isSameNormal * isSameDepth;
88     }
89         
90     v2f vertRobert( appdata_img v )
91     {
92         v2f o;
93         o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
94         
95         float2 uv = v.texcoord.xy;
96         o.uv[
0] = uv;
97         
98         #
if UNITY_UV_STARTS_AT_TOP
99         
if (_MainTex_TexelSize.y < 0)
100             uv.y =
1-uv.y;
101         #endif
102                 
103         
// calc coord for the X pattern
104         
// maybe nicer TODO for the future: 'rotated triangles'
105         
106         o.uv[
1] = uv + _MainTex_TexelSize.xy * half2(1,1) * _SampleDistance;
107         o.uv[
2] = uv + _MainTex_TexelSize.xy * half2(-1,-1) * _SampleDistance;
108         o.uv[
3] = uv + _MainTex_TexelSize.xy * half2(-1,1) * _SampleDistance;
109         o.uv[
4] = uv + _MainTex_TexelSize.xy * half2(1,-1) * _SampleDistance;
110                  
111         
return o;
112     }
113     
114     v2f vertThin( appdata_img v )
115     {
116         v2f o;
117         o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
118         
119         float2 uv = v.texcoord.xy;
120         o.uv[
0] = uv;
121         
122         #
if UNITY_UV_STARTS_AT_TOP
123         
if (_MainTex_TexelSize.y < 0)
124             uv.y =
1-uv.y;
125         #endif
126         
127         o.uv[
1] = uv;
128         o.uv[
4] = uv;
129                 
130         
// offsets for two additional samples
131         o.uv[
2] = uv + float2(-_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance;
132         o.uv[
3] = uv + float2(+_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance;
133         
134         
return o;
135     }
136      
137     v2fd vertD( appdata_img v )
138     {
139         v2fd o;
140         o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
141         
142         float2 uv = v.texcoord.xy;
143         o.uv[
0] = uv;
144         
145         #
if UNITY_UV_STARTS_AT_TOP
146         
if (_MainTex_TexelSize.y < 0)
147             uv.y =
1-uv.y;
148         #endif
149         
150         o.uv[
1] = uv;
151         
152         
return o;
153     }
154
155     float4 fragDCheap(v2fd i) : SV_Target
156     {
157         
// inspired by borderlands implementation of popular "sobel filter"
158
159         
float centerDepth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv[1]));
160         float4 depthsDiag;
161         float4 depthsAxis;
162
163         float2 uvDist = _SampleDistance * _MainTex_TexelSize.xy;
164
165         depthsDiag.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[
1]+uvDist)); // TR
166         depthsDiag.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[
1]+uvDist*float2(-1,1))); // TL
167         depthsDiag.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[
1]-uvDist*float2(-1,1))); // BR
168         depthsDiag.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[
1]-uvDist)); // BL
169
170         depthsAxis.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[
1]+uvDist*float2(0,1))); // T
171         depthsAxis.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[
1]-uvDist*float2(1,0))); // L
172         depthsAxis.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[
1]+uvDist*float2(1,0))); // R
173         depthsAxis.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[
1]-uvDist*float2(0,1))); // B
174
175         depthsDiag -= centerDepth;
176         depthsAxis /= centerDepth;
177
178         
const float4 HorizDiagCoeff = float4(1,1,-1,-1);
179         
const float4 VertDiagCoeff = float4(-1,1,-1,1);
180         
const float4 HorizAxisCoeff = float4(1,0,0,-1);
181         
const float4 VertAxisCoeff = float4(0,1,-1,0);
182
183         float4 SobelH = depthsDiag * HorizDiagCoeff + depthsAxis * HorizAxisCoeff;
184         float4 SobelV = depthsDiag * VertDiagCoeff + depthsAxis * VertAxisCoeff;
185
186         
float SobelX = dot(SobelH, float4(1,1,1,1));
187         
float SobelY = dot(SobelV, float4(1,1,1,1));
188         
float Sobel = sqrt(SobelX * SobelX + SobelY * SobelY);
189
190         Sobel =
1.0-pow(saturate(Sobel), _Exponent);
191         
return Sobel * lerp(tex2D(_MainTex, i.uv[0].xy), _BgColor, _BgFade);
192     }
193
194     
// pretty much also just a sobel filter, except for that edges "outside" the silhouette get discarded
195     
// which makes it compatible with other depth based post fx
196
197     float4 fragD(v2fd i) : SV_Target
198     {
199         
// inspired by borderlands implementation of popular "sobel filter"
200
201         
float centerDepth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv[1]));
202         float4 depthsDiag;
203         float4 depthsAxis;
204
205         float2 uvDist = _SampleDistance * _MainTex_TexelSize.xy;
206
207         depthsDiag.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[
1]+uvDist)); // TR
208         depthsDiag.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[
1]+uvDist*float2(-1,1))); // TL
209         depthsDiag.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[
1]-uvDist*float2(-1,1))); // BR
210         depthsDiag.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[
1]-uvDist)); // BL
211
212         depthsAxis.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[
1]+uvDist*float2(0,1))); // T
213         depthsAxis.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[
1]-uvDist*float2(1,0))); // L
214         depthsAxis.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[
1]+uvDist*float2(1,0))); // R
215         depthsAxis.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[
1]-uvDist*float2(0,1))); // B
216
217         
// make it work nicely with depth based image effects such as depth of field:
218         depthsDiag = (depthsDiag > centerDepth.xxxx) ? depthsDiag : centerDepth.xxxx;
219         depthsAxis = (depthsAxis > centerDepth.xxxx) ? depthsAxis : centerDepth.xxxx;
220
221         depthsDiag -= centerDepth;
222         depthsAxis /= centerDepth;
223
224         
const float4 HorizDiagCoeff = float4(1,1,-1,-1);
225         
const float4 VertDiagCoeff = float4(-1,1,-1,1);
226         
const float4 HorizAxisCoeff = float4(1,0,0,-1);
227         
const float4 VertAxisCoeff = float4(0,1,-1,0);
228
229         float4 SobelH = depthsDiag * HorizDiagCoeff + depthsAxis * HorizAxisCoeff;
230         float4 SobelV = depthsDiag * VertDiagCoeff + depthsAxis * VertAxisCoeff;
231
232         
float SobelX = dot(SobelH, float4(1,1,1,1));
233         
float SobelY = dot(SobelV, float4(1,1,1,1));
234         
float Sobel = sqrt(SobelX * SobelX + SobelY * SobelY);
235
236         Sobel =
1.0-pow(saturate(Sobel), _Exponent);
237         
return Sobel * lerp(tex2D(_MainTex, i.uv[0].xy), _BgColor, _BgFade);
238     }
239
240     half4 fragRobert(v2f i) : SV_Target {
241         half4 sample1 = tex2D(_CameraDepthNormalsTexture, i.uv[
1].xy);
242         half4 sample2 = tex2D(_CameraDepthNormalsTexture, i.uv[
2].xy);
243         half4 sample3 = tex2D(_CameraDepthNormalsTexture, i.uv[
3].xy);
244         half4 sample4 = tex2D(_CameraDepthNormalsTexture, i.uv[
4].xy);
245
246         half edge =
1.0;
247         
248         edge *= CheckSame(sample1.xy, DecodeFloatRG(sample1.zw), sample2);
249         edge *= CheckSame(sample3.xy, DecodeFloatRG(sample3.zw), sample4);
250
251         
return edge * lerp(tex2D(_MainTex, i.uv[0]), _BgColor, _BgFade);
252     }
253     
254     half4 fragThin (v2f i) : SV_Target
255     {
256         half4 original = tex2D(_MainTex, i.uv[
0]);
257         
258         half4 center = tex2D (_CameraDepthNormalsTexture, i.uv[
1]);
259         half4 sample1 = tex2D (_CameraDepthNormalsTexture, i.uv[
2]);
260         half4 sample2 = tex2D (_CameraDepthNormalsTexture, i.uv[
3]);
261         
262         
// encoded normal
263         half2 centerNormal = center.xy;
264         
// decoded depth
265         
float centerDepth = DecodeFloatRG (center.zw);
266         
267         half edge =
1.0;
268         
269         edge *= CheckSame(centerNormal, centerDepth, sample1);
270         edge *= CheckSame(centerNormal, centerDepth, sample2);
271             
272         
return edge * lerp(original, _BgColor, _BgFade);
273     }
274     
275     ENDCG
276     
277 Subshader {
278  Pass {
279       ZTest Always Cull Off ZWrite Off
280
281       CGPROGRAM
282       #pragma vertex vertThin
283       #pragma fragment fragThin
284       ENDCG
285   }
286  Pass {
287       ZTest Always Cull Off ZWrite Off
288
289       CGPROGRAM
290       #pragma vertex vertRobert
291       #pragma fragment fragRobert
292       ENDCG
293   }
294  Pass {
295       ZTest Always Cull Off ZWrite Off
296
297       CGPROGRAM
298       #pragma target
3.0
299       #pragma vertex vertD
300       #pragma fragment fragDCheap
301       ENDCG
302   }
303  Pass {
304       ZTest Always Cull Off ZWrite Off
305
306       CGPROGRAM
307       #pragma target
3.0
308       #pragma vertex vertD
309       #pragma fragment fragD
310       ENDCG
311   }
312  Pass {
313       ZTest Always Cull Off ZWrite Off
314
315       CGPROGRAM
316       #pragma target
3.0
317       #pragma vertex vertLum
318       #pragma fragment fragLum
319       ENDCG
320   }
321 }
322
323 Fallback off
324     
325 }
// shader


Gõ tìm kiếm nhanh...