1  Shader "Hidden/Dof/DepthOfField34" {
2     Properties {
3         _MainTex (
"Base", 2D) = "" {}
4         _TapLowBackground (
"TapLowBackground", 2D) = "" {}
5         _TapLowForeground (
"TapLowForeground", 2D) = "" {}
6         _TapMedium (
"TapMedium", 2D) = "" {}
7     }
8
9     CGINCLUDE
10     
11     #include
"UnityCG.cginc"
12     
13     
struct v2f {
14         half4 pos : SV_POSITION;
15         half2 uv1 : TEXCOORD0;
16     };
17     
18     
struct v2fDofApply {
19         half4 pos : SV_POSITION;
20         half2 uv : TEXCOORD0;
21     };
22     
23     
struct v2fRadius {
24         half4 pos : SV_POSITION;
25         half2 uv : TEXCOORD0;
26         half4 uv1[
4] : TEXCOORD1;
27     };
28     
29     
struct v2fDown {
30         half4 pos : SV_POSITION;
31         half2 uv0 : TEXCOORD0;
32         half2 uv[
2] : TEXCOORD1;
33     };
34             
35     sampler2D _MainTex;
36     sampler2D_float _CameraDepthTexture;
37     sampler2D _TapLowBackground;
38     sampler2D _TapLowForeground;
39     sampler2D _TapMedium;
40             
41     half4 _CurveParams;
42     half _ForegroundBlurExtrude;
43     uniform half3 _Threshhold;
44     uniform float4 _MainTex_TexelSize;
45     uniform float2 _InvRenderTargetSize;
46     
47     v2f vert( appdata_img v ) {
48         v2f o;
49         o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
50         o.uv1.xy = v.texcoord.xy;
51         
return o;
52     }
53
54     v2fRadius vertWithRadius( appdata_img v ) {
55         v2fRadius o;
56         o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
57         o.uv.xy = v.texcoord.xy;
58
59         
const half2 blurOffsets[4] = {
60             half2(-
0.5, +1.5),
61             half2(+
0.5, -1.5),
62             half2(+
1.5, +0.5),
63             half2(-
1.5, -0.5)
64         };
65                 
66         o.uv1[
0].xy = v.texcoord.xy + 5.0 * _MainTex_TexelSize.xy * blurOffsets[0];
67         o.uv1[
1].xy = v.texcoord.xy + 5.0 * _MainTex_TexelSize.xy * blurOffsets[1];
68         o.uv1[
2].xy = v.texcoord.xy + 5.0 * _MainTex_TexelSize.xy * blurOffsets[2];
69         o.uv1[
3].xy = v.texcoord.xy + 5.0 * _MainTex_TexelSize.xy * blurOffsets[3];
70         
71         o.uv1[
0].zw = v.texcoord.xy + 3.0 * _MainTex_TexelSize.xy * blurOffsets[0];
72         o.uv1[
1].zw = v.texcoord.xy + 3.0 * _MainTex_TexelSize.xy * blurOffsets[1];
73         o.uv1[
2].zw = v.texcoord.xy + 3.0 * _MainTex_TexelSize.xy * blurOffsets[2];
74         o.uv1[
3].zw = v.texcoord.xy + 3.0 * _MainTex_TexelSize.xy * blurOffsets[3];
75         
76         
return o;
77     }
78     
79     v2fDofApply vertDofApply( appdata_img v ) {
80         v2fDofApply o;
81         o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
82         o.uv.xy = v.texcoord.xy;
83         
return o;
84     }
85         
86     v2fDown vertDownsampleWithCocConserve(appdata_img v) {
87         v2fDown o;
88         o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
89         o.uv0.xy = v.texcoord.xy;
90         o.uv[
0].xy = v.texcoord.xy + half2(-1.0,-1.0) * _InvRenderTargetSize;
91         o.uv[
1].xy = v.texcoord.xy + half2(1.0,-1.0) * _InvRenderTargetSize;
92         
return o;
93     }
94     
95     half4 BokehPrereqs (sampler2D tex, half4 uv1[
4], half4 center, half considerCoc) {
96         
97         
// @NOTE 1:
98         
// we are checking for 3 things in order to create a bokeh.
99         
// goal is to get the highest bang for the buck.
100         
// 1.) contrast/frequency should be very high (otherwise bokeh mostly unvisible)
101         
// 2.) luminance should be high
102         
// 3.) no occluder nearby (stored in alpha channel)
103         
104         
// @NOTE 2: about the alpha channel in littleBlur:
105         
// the alpha channel stores an heuristic on how likely it is
106         
// that there is no bokeh occluder nearby.
107         
// if we didn't' check for that, we'd get very noise bokeh
108         
// popping because of the sudden contrast changes
109
110         half4 sampleA = tex2D(tex, uv1[
0].zw);
111         half4 sampleB = tex2D(tex, uv1[
1].zw);
112         half4 sampleC = tex2D(tex, uv1[
2].zw);
113         half4 sampleD = tex2D(tex, uv1[
3].zw);
114         
115         half4 littleBlur =
0.125 * (sampleA + sampleB + sampleC + sampleD);
116         
117         sampleA = tex2D(tex, uv1[
0].xy);
118         sampleB = tex2D(tex, uv1[
1].xy);
119         sampleC = tex2D(tex, uv1[
2].xy);
120         sampleD = tex2D(tex, uv1[
3].xy);
121
122         littleBlur +=
0.125 * (sampleA + sampleB + sampleC + sampleD);
123                 
124         littleBlur = lerp (littleBlur, center, saturate(
100.0 * considerCoc * abs(littleBlur.a - center.a)));
125                 
126         
return littleBlur;
127     }
128     
129     half4 fragDownsampleWithCocConserve(v2fDown i) : SV_Target {
130         half2 rowOfs[
4];
131         
132         rowOfs[
0] = half2(0.0, 0.0);
133         rowOfs[
1] = half2(0.0, _InvRenderTargetSize.y);
134         rowOfs[
2] = half2(0.0, _InvRenderTargetSize.y) * 2.0;
135         rowOfs[
3] = half2(0.0, _InvRenderTargetSize.y) * 3.0;
136         
137         half4 color = tex2D(_MainTex, i.uv0.xy);
138             
139         half4 sampleA = tex2D(_MainTex, i.uv[
0].xy + rowOfs[0]);
140         half4 sampleB = tex2D(_MainTex, i.uv[
1].xy + rowOfs[0]);
141         half4 sampleC = tex2D(_MainTex, i.uv[
0].xy + rowOfs[2]);
142         half4 sampleD = tex2D(_MainTex, i.uv[
1].xy + rowOfs[2]);
143         
144         color += sampleA + sampleB + sampleC + sampleD;
145         color *=
0.2;
146         
147         
// @NOTE we are doing max on the alpha channel for 2 reasons:
148         
// 1) foreground blur likes a slightly bigger radius
149         
// 2) otherwise we get an ugly outline between high blur- and medium blur-areas
150         
// drawback: we get a little bit of color bleeding
151         
152         color.a = max(max(sampleA.a, sampleB.a), max(sampleC.a, sampleD.a));
153         
154         
return color;
155     }
156     
157     half4 fragDofApplyBg (v2fDofApply i) : SV_Target {
158         half4 tapHigh = tex2D (_MainTex, i.uv.xy);
159         
160         #
if UNITY_UV_STARTS_AT_TOP
161         
if (_MainTex_TexelSize.y < 0)
162             i.uv.xy = i.uv.xy * half2(
1,-1)+half2(0,1);
163         #endif
164         
165         half4 tapLow = tex2D (_TapLowBackground, i.uv.xy);
// already mixed with medium blur
166         tapHigh = lerp (tapHigh, tapLow, tapHigh.a);
167         
return tapHigh;
168     }
169     
170     half4 fragDofApplyBgDebug (v2fDofApply i) : SV_Target {
171         half4 tapHigh = tex2D (_MainTex, i.uv.xy);
172         
173         half4 tapLow = tex2D (_TapLowBackground, i.uv.xy);
174         
175         half4 tapMedium = tex2D (_TapMedium, i.uv.xy);
176         tapMedium.rgb = (tapMedium.rgb + half3 (
1, 1, 0)) * 0.5;
177         tapLow.rgb = (tapLow.rgb + half3 (
0, 1, 0)) * 0.5;
178         
179         tapLow = lerp (tapMedium, tapLow, saturate (tapLow.a * tapLow.a));
180         tapLow = tapLow *
0.5 + tex2D (_TapLowBackground, i.uv.xy) * 0.5;
181
182         
return lerp (tapHigh, tapLow, tapHigh.a);
183     }
184     
185     half4 fragDofApplyFg (v2fDofApply i) : SV_Target {
186         half4 fgBlur = tex2D(_TapLowForeground, i.uv.xy);
187         
188         #
if UNITY_UV_STARTS_AT_TOP
189         
if (_MainTex_TexelSize.y < 0)
190             i.uv.xy = i.uv.xy * half2(
1,-1)+half2(0,1);
191         #endif
192                 
193         half4 fgColor = tex2D(_MainTex,i.uv.xy);
194                 
195         
//fgBlur.a = saturate(fgBlur.a*_ForegroundBlurWeight+saturate(fgColor.a-fgBlur.a));
196         
//fgBlur.a = max (fgColor.a, (2.0 * fgBlur.a - fgColor.a)) * _ForegroundBlurExtrude;
197         fgBlur.a = max(fgColor.a, fgBlur.a * _ForegroundBlurExtrude);
//max (fgColor.a, (2.0*fgBlur.a-fgColor.a)) * _ForegroundBlurExtrude;
198         
199         
return lerp (fgColor, fgBlur, saturate(fgBlur.a));
200     }
201     
202     half4 fragDofApplyFgDebug (v2fDofApply i) : SV_Target {
203         half4 fgBlur = tex2D(_TapLowForeground, i.uv.xy);
204                     
205         half4 fgColor = tex2D(_MainTex,i.uv.xy);
206         
207         fgBlur.a = max(fgColor.a, fgBlur.a * _ForegroundBlurExtrude);
//max (fgColor.a, (2.0*fgBlur.a-fgColor.a)) * _ForegroundBlurExtrude;
208         
209         half4 tapMedium = half4 (
1, 1, 0, fgBlur.a);
210         tapMedium.rgb =
0.5 * (tapMedium.rgb + fgColor.rgb);
211         
212         fgBlur.rgb =
0.5 * (fgBlur.rgb + half3(0,1,0));
213         fgBlur.rgb = lerp (tapMedium.rgb, fgBlur.rgb, saturate (fgBlur.a * fgBlur.a));
214         
215         
return lerp ( fgColor, fgBlur, saturate(fgBlur.a));
216     }
217         
218     half4 fragCocBg (v2f i) : SV_Target {
219         
220         
float d = SAMPLE_DEPTH_TEXTURE (_CameraDepthTexture, i.uv1.xy);
221         d = Linear01Depth (d);
222         half coc =
0.0;
223         
224         half focalDistance01 = _CurveParams.w + _CurveParams.z;
225         
226         
if (d > focalDistance01)
227             coc = (d - focalDistance01);
228     
229         coc = saturate (coc * _CurveParams.y);
230         
return coc;
231     }
232     
233     half4 fragCocFg (v2f i) : SV_Target {
234         half4 color = tex2D (_MainTex, i.uv1.xy);
235         color.a =
0.0;
236
237         #
if UNITY_UV_STARTS_AT_TOP
238         
if (_MainTex_TexelSize.y < 0)
239             i.uv1.xy = i.uv1.xy * half2(
1,-1)+half2(0,1);
240         #endif
241
242         
float d = SAMPLE_DEPTH_TEXTURE (_CameraDepthTexture, i.uv1.xy);
243         d = Linear01Depth (d);
244         
245         half focalDistance01 = (_CurveParams.w - _CurveParams.z);
246         
247         
if (d < focalDistance01)
248             color.a = (focalDistance01 - d);
249         
250         color.a = saturate (color.a * _CurveParams.x);
251         
return color;
252     }
253     
254     
// not being used atm
255     
256     half4 fragMask (v2f i) : SV_Target {
257         
return half4(0,0,0,0);
258     }
259     
260     
// used for simple one one blend
261     
262     half4 fragAddBokeh (v2f i) : SV_Target {
263         half4
from = tex2D( _MainTex, i.uv1.xy );
264         
return from;
265     }
266     
267     half4 fragAddFgBokeh (v2f i) : SV_Target {
268         half4
from = tex2D( _MainTex, i.uv1.xy );
269         
return from;
270     }
271         
272     half4 fragDarkenForBokeh(v2fRadius i) : SV_Target {
273         half4 fromOriginal = tex2D(_MainTex, i.uv.xy);
274         half4 lowRez = BokehPrereqs (_MainTex, i.uv1, fromOriginal, _Threshhold.z);
275         half4 outColor = half4(
0,0,0, fromOriginal.a);
276         half modulate = fromOriginal.a;
277         
278         
// this code imitates the if-then-else conditions below
279         half2 conditionCheck = half2( dot(abs(fromOriginal.rgb-lowRez.rgb), half3(
0.3,0.5,0.2)), Luminance(fromOriginal.rgb));
280         conditionCheck *= fromOriginal.a;
281         conditionCheck = saturate(_Threshhold.xy - conditionCheck);
282         outColor = lerp (outColor, fromOriginal, saturate (dot(conditionCheck, half2(
1000.0,1000.0))));
283         
284         
/*
285         
if ( abs(dot(fromOriginal.rgb - lowRez.rgb, half3 (0.3,0.5,0.2))) * modulate < _Threshhold.x)
286             outColor = fromOriginal; // no darkening
287         
if (Luminance(fromOriginal.rgb) * modulate < _Threshhold.y)
288             outColor = fromOriginal; // no darkening
289         
if (lowRez.a < _Threshhold.z) // need to make foreground not cast false bokeh's
290             outColor = fromOriginal; // no darkenin
291         */

292          
293         
return outColor;
294     }
295  
296     half4 fragExtractAndAddToBokeh (v2fRadius i) : SV_Target {
297         half4
from = tex2D(_MainTex, i.uv.xy);
298         half4 lowRez = BokehPrereqs(_MainTex, i.uv1,
from, _Threshhold.z);
299         half4 outColor =
from;
300
301         
// this code imitates the if-then-else conditions below
302         half2 conditionCheck = half2( dot(abs(
from.rgb-lowRez.rgb), half3(0.3,0.5,0.2)), Luminance(from.rgb));
303         conditionCheck *=
from.a;
304         conditionCheck = saturate(_Threshhold.xy - conditionCheck);
305         outColor = lerp (outColor, half4(
0,0,0,0), saturate (dot(conditionCheck, half2(1000.0,1000.0))));
306         
307         
/*
308         
if ( abs(dot(from.rgb - lowRez.rgb, half3 (0.3,0.5,0.2))) * modulate < _Threshhold.x)
309             outColor = half4(
0,0,0,0); // don't add
310         
if (Luminance(from.rgb) * modulate < _Threshhold.y)
311             outColor = half4(
0,0,0,0); // don't add
312         
if (lowRez.a < _Threshhold.z) // need to make foreground not cast false bokeh's
313             outColor = half4(
0,0,0,0); // don't add
314         */

315                             
316         
return outColor;
317     }
318  
319     ENDCG
320     
321 Subshader {
322  
323  
// pass 0
324  
325  Pass {
326       ZTest Always Cull Off ZWrite Off
327
328       CGPROGRAM
329       #pragma vertex vertDofApply
330       #pragma fragment fragDofApplyBg
331       
332       ENDCG
333     }
334
335  
// pass 1
336  
337  Pass {
338       ZTest Always Cull Off ZWrite Off
339       ColorMask RGB
340
341       CGPROGRAM
342       #pragma vertex vertDofApply
343       #pragma fragment fragDofApplyFgDebug
344
345       ENDCG
346     }
347
348  
// pass 2
349
350  Pass {
351       ZTest Always Cull Off ZWrite Off
352       ColorMask RGB
353
354       CGPROGRAM
355       #pragma vertex vertDofApply
356       #pragma fragment fragDofApplyBgDebug
357
358       ENDCG
359     }
360     
361     
362  
363  
// pass 3
364  
365  Pass {
366       ZTest Always Cull Off ZWrite Off
367       ColorMask A
368
369       CGPROGRAM
370       #pragma vertex vert
371       #pragma fragment fragCocBg
372
373       ENDCG
374     }
375         
376     
377  
// pass 4
378
379   
380  Pass {
381       ZTest Always Cull Off ZWrite Off
382       ColorMask RGB
383       
//Blend One One
384
385       CGPROGRAM
386       #pragma vertex vertDofApply
387       #pragma fragment fragDofApplyFg
388       
389       ENDCG
390     }
391
392  
// pass 5
393   
394  Pass {
395       ZTest Always Cull Off ZWrite Off
396       ColorMask ARGB
397
398       CGPROGRAM
399       #pragma vertex vert
400       #pragma fragment fragCocFg
401
402       ENDCG
403     }
404
405  
// pass 6
406  
407  Pass {
408       ZTest Always Cull Off ZWrite Off
409
410       CGPROGRAM
411       #pragma vertex vertDownsampleWithCocConserve
412       #pragma fragment fragDownsampleWithCocConserve
413
414       ENDCG
415     }
416
417  
// pass 7
418  
// not being used atm
419  
420  Pass {
421       ZTest Always Cull Off ZWrite Off
422       ColorMask RGBA
423
424       CGPROGRAM
425       #pragma vertex vert
426       #pragma fragment fragMask
427
428       ENDCG
429     }
430
431  
// pass 8
432  
433  Pass {
434       ZTest Always Cull Off ZWrite Off
435       Blend SrcAlpha OneMinusSrcAlpha
436       ColorMask RGB
437
438       CGPROGRAM
439       #pragma vertex vert
440       #pragma fragment fragAddBokeh
441
442       ENDCG
443     }
444     
445  
// pass 9
446  
447  Pass {
448       ZTest Always Cull Off ZWrite Off
449       Blend One One
450       ColorMask RGB
451
452       CGPROGRAM
453       #pragma vertex vertWithRadius
454       #pragma fragment fragExtractAndAddToBokeh
455
456       ENDCG
457     }
458     
459  
// pass 10
460  
461  Pass {
462       ZTest Always Cull Off ZWrite Off
463
464       CGPROGRAM
465       #pragma vertex vertWithRadius
466       #pragma fragment fragDarkenForBokeh
467
468       ENDCG
469     }
470     
471  
// pass 11
472  
473  Pass {
474       ZTest Always Cull Off ZWrite Off
475
476       CGPROGRAM
477       #pragma vertex vertWithRadius
478       #pragma fragment fragExtractAndAddToBokeh
479
480       ENDCG
481     }
482   }
483   
484 Fallback off
485
486 }


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