| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488 |
- // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
- Shader "Hidden/Dof/DepthOfField34" {
- Properties {
- _MainTex ("Base", 2D) = "" {}
- _TapLowBackground ("TapLowBackground", 2D) = "" {}
- _TapLowForeground ("TapLowForeground", 2D) = "" {}
- _TapMedium ("TapMedium", 2D) = "" {}
- }
- CGINCLUDE
-
- #include "UnityCG.cginc"
-
- struct v2f {
- half4 pos : SV_POSITION;
- half2 uv1 : TEXCOORD0;
- };
-
- struct v2fDofApply {
- half4 pos : SV_POSITION;
- half2 uv : TEXCOORD0;
- };
-
- struct v2fRadius {
- half4 pos : SV_POSITION;
- half2 uv : TEXCOORD0;
- half4 uv1[4] : TEXCOORD1;
- };
-
- struct v2fDown {
- half4 pos : SV_POSITION;
- half2 uv0 : TEXCOORD0;
- half2 uv[2] : TEXCOORD1;
- };
-
- sampler2D _MainTex;
- sampler2D_float _CameraDepthTexture;
- sampler2D _TapLowBackground;
- sampler2D _TapLowForeground;
- sampler2D _TapMedium;
-
- half4 _CurveParams;
- half _ForegroundBlurExtrude;
- uniform half3 _Threshhold;
- uniform float4 _MainTex_TexelSize;
- uniform float2 _InvRenderTargetSize;
-
- v2f vert( appdata_img v ) {
- v2f o;
- o.pos = UnityObjectToClipPos (v.vertex);
- o.uv1.xy = v.texcoord.xy;
- return o;
- }
- v2fRadius vertWithRadius( appdata_img v ) {
- v2fRadius o;
- o.pos = UnityObjectToClipPos(v.vertex);
- o.uv.xy = v.texcoord.xy;
- const half2 blurOffsets[4] = {
- half2(-0.5, +1.5),
- half2(+0.5, -1.5),
- half2(+1.5, +0.5),
- half2(-1.5, -0.5)
- };
-
- o.uv1[0].xy = v.texcoord.xy + 5.0 * _MainTex_TexelSize.xy * blurOffsets[0];
- o.uv1[1].xy = v.texcoord.xy + 5.0 * _MainTex_TexelSize.xy * blurOffsets[1];
- o.uv1[2].xy = v.texcoord.xy + 5.0 * _MainTex_TexelSize.xy * blurOffsets[2];
- o.uv1[3].xy = v.texcoord.xy + 5.0 * _MainTex_TexelSize.xy * blurOffsets[3];
-
- o.uv1[0].zw = v.texcoord.xy + 3.0 * _MainTex_TexelSize.xy * blurOffsets[0];
- o.uv1[1].zw = v.texcoord.xy + 3.0 * _MainTex_TexelSize.xy * blurOffsets[1];
- o.uv1[2].zw = v.texcoord.xy + 3.0 * _MainTex_TexelSize.xy * blurOffsets[2];
- o.uv1[3].zw = v.texcoord.xy + 3.0 * _MainTex_TexelSize.xy * blurOffsets[3];
-
- return o;
- }
-
- v2fDofApply vertDofApply( appdata_img v ) {
- v2fDofApply o;
- o.pos = UnityObjectToClipPos(v.vertex);
- o.uv.xy = v.texcoord.xy;
- return o;
- }
-
- v2fDown vertDownsampleWithCocConserve(appdata_img v) {
- v2fDown o;
- o.pos = UnityObjectToClipPos(v.vertex);
- o.uv0.xy = v.texcoord.xy;
- o.uv[0].xy = v.texcoord.xy + half2(-1.0,-1.0) * _InvRenderTargetSize;
- o.uv[1].xy = v.texcoord.xy + half2(1.0,-1.0) * _InvRenderTargetSize;
- return o;
- }
-
- half4 BokehPrereqs (sampler2D tex, half4 uv1[4], half4 center, half considerCoc) {
-
- // @NOTE 1:
- // we are checking for 3 things in order to create a bokeh.
- // goal is to get the highest bang for the buck.
- // 1.) contrast/frequency should be very high (otherwise bokeh mostly unvisible)
- // 2.) luminance should be high
- // 3.) no occluder nearby (stored in alpha channel)
-
- // @NOTE 2: about the alpha channel in littleBlur:
- // the alpha channel stores an heuristic on how likely it is
- // that there is no bokeh occluder nearby.
- // if we didn't' check for that, we'd get very noise bokeh
- // popping because of the sudden contrast changes
- half4 sampleA = tex2D(tex, uv1[0].zw);
- half4 sampleB = tex2D(tex, uv1[1].zw);
- half4 sampleC = tex2D(tex, uv1[2].zw);
- half4 sampleD = tex2D(tex, uv1[3].zw);
-
- half4 littleBlur = 0.125 * (sampleA + sampleB + sampleC + sampleD);
-
- sampleA = tex2D(tex, uv1[0].xy);
- sampleB = tex2D(tex, uv1[1].xy);
- sampleC = tex2D(tex, uv1[2].xy);
- sampleD = tex2D(tex, uv1[3].xy);
- littleBlur += 0.125 * (sampleA + sampleB + sampleC + sampleD);
-
- littleBlur = lerp (littleBlur, center, saturate(100.0 * considerCoc * abs(littleBlur.a - center.a)));
-
- return littleBlur;
- }
-
- half4 fragDownsampleWithCocConserve(v2fDown i) : SV_Target {
- half2 rowOfs[4];
-
- rowOfs[0] = half2(0.0, 0.0);
- rowOfs[1] = half2(0.0, _InvRenderTargetSize.y);
- rowOfs[2] = half2(0.0, _InvRenderTargetSize.y) * 2.0;
- rowOfs[3] = half2(0.0, _InvRenderTargetSize.y) * 3.0;
-
- half4 color = tex2D(_MainTex, i.uv0.xy);
-
- half4 sampleA = tex2D(_MainTex, i.uv[0].xy + rowOfs[0]);
- half4 sampleB = tex2D(_MainTex, i.uv[1].xy + rowOfs[0]);
- half4 sampleC = tex2D(_MainTex, i.uv[0].xy + rowOfs[2]);
- half4 sampleD = tex2D(_MainTex, i.uv[1].xy + rowOfs[2]);
-
- color += sampleA + sampleB + sampleC + sampleD;
- color *= 0.2;
-
- // @NOTE we are doing max on the alpha channel for 2 reasons:
- // 1) foreground blur likes a slightly bigger radius
- // 2) otherwise we get an ugly outline between high blur- and medium blur-areas
- // drawback: we get a little bit of color bleeding
-
- color.a = max(max(sampleA.a, sampleB.a), max(sampleC.a, sampleD.a));
-
- return color;
- }
-
- half4 fragDofApplyBg (v2fDofApply i) : SV_Target {
- half4 tapHigh = tex2D (_MainTex, i.uv.xy);
-
- #if UNITY_UV_STARTS_AT_TOP
- if (_MainTex_TexelSize.y < 0)
- i.uv.xy = i.uv.xy * half2(1,-1)+half2(0,1);
- #endif
-
- half4 tapLow = tex2D (_TapLowBackground, i.uv.xy); // already mixed with medium blur
- tapHigh = lerp (tapHigh, tapLow, tapHigh.a);
- return tapHigh;
- }
-
- half4 fragDofApplyBgDebug (v2fDofApply i) : SV_Target {
- half4 tapHigh = tex2D (_MainTex, i.uv.xy);
-
- half4 tapLow = tex2D (_TapLowBackground, i.uv.xy);
-
- half4 tapMedium = tex2D (_TapMedium, i.uv.xy);
- tapMedium.rgb = (tapMedium.rgb + half3 (1, 1, 0)) * 0.5;
- tapLow.rgb = (tapLow.rgb + half3 (0, 1, 0)) * 0.5;
-
- tapLow = lerp (tapMedium, tapLow, saturate (tapLow.a * tapLow.a));
- tapLow = tapLow * 0.5 + tex2D (_TapLowBackground, i.uv.xy) * 0.5;
- return lerp (tapHigh, tapLow, tapHigh.a);
- }
-
- half4 fragDofApplyFg (v2fDofApply i) : SV_Target {
- half4 fgBlur = tex2D(_TapLowForeground, i.uv.xy);
-
- #if UNITY_UV_STARTS_AT_TOP
- if (_MainTex_TexelSize.y < 0)
- i.uv.xy = i.uv.xy * half2(1,-1)+half2(0,1);
- #endif
-
- half4 fgColor = tex2D(_MainTex,i.uv.xy);
-
- //fgBlur.a = saturate(fgBlur.a*_ForegroundBlurWeight+saturate(fgColor.a-fgBlur.a));
- //fgBlur.a = max (fgColor.a, (2.0 * fgBlur.a - fgColor.a)) * _ForegroundBlurExtrude;
- fgBlur.a = max(fgColor.a, fgBlur.a * _ForegroundBlurExtrude); //max (fgColor.a, (2.0*fgBlur.a-fgColor.a)) * _ForegroundBlurExtrude;
-
- return lerp (fgColor, fgBlur, saturate(fgBlur.a));
- }
-
- half4 fragDofApplyFgDebug (v2fDofApply i) : SV_Target {
- half4 fgBlur = tex2D(_TapLowForeground, i.uv.xy);
-
- half4 fgColor = tex2D(_MainTex,i.uv.xy);
-
- fgBlur.a = max(fgColor.a, fgBlur.a * _ForegroundBlurExtrude); //max (fgColor.a, (2.0*fgBlur.a-fgColor.a)) * _ForegroundBlurExtrude;
-
- half4 tapMedium = half4 (1, 1, 0, fgBlur.a);
- tapMedium.rgb = 0.5 * (tapMedium.rgb + fgColor.rgb);
-
- fgBlur.rgb = 0.5 * (fgBlur.rgb + half3(0,1,0));
- fgBlur.rgb = lerp (tapMedium.rgb, fgBlur.rgb, saturate (fgBlur.a * fgBlur.a));
-
- return lerp ( fgColor, fgBlur, saturate(fgBlur.a));
- }
-
- half4 fragCocBg (v2f i) : SV_Target {
-
- float d = SAMPLE_DEPTH_TEXTURE (_CameraDepthTexture, i.uv1.xy);
- d = Linear01Depth (d);
- half coc = 0.0;
-
- half focalDistance01 = _CurveParams.w + _CurveParams.z;
-
- if (d > focalDistance01)
- coc = (d - focalDistance01);
-
- coc = saturate (coc * _CurveParams.y);
- return coc;
- }
-
- half4 fragCocFg (v2f i) : SV_Target {
- half4 color = tex2D (_MainTex, i.uv1.xy);
- color.a = 0.0;
- #if UNITY_UV_STARTS_AT_TOP
- if (_MainTex_TexelSize.y < 0)
- i.uv1.xy = i.uv1.xy * half2(1,-1)+half2(0,1);
- #endif
- float d = SAMPLE_DEPTH_TEXTURE (_CameraDepthTexture, i.uv1.xy);
- d = Linear01Depth (d);
-
- half focalDistance01 = (_CurveParams.w - _CurveParams.z);
-
- if (d < focalDistance01)
- color.a = (focalDistance01 - d);
-
- color.a = saturate (color.a * _CurveParams.x);
- return color;
- }
-
- // not being used atm
-
- half4 fragMask (v2f i) : SV_Target {
- return half4(0,0,0,0);
- }
-
- // used for simple one one blend
-
- half4 fragAddBokeh (v2f i) : SV_Target {
- half4 from = tex2D( _MainTex, i.uv1.xy );
- return from;
- }
-
- half4 fragAddFgBokeh (v2f i) : SV_Target {
- half4 from = tex2D( _MainTex, i.uv1.xy );
- return from;
- }
-
- half4 fragDarkenForBokeh(v2fRadius i) : SV_Target {
- half4 fromOriginal = tex2D(_MainTex, i.uv.xy);
- half4 lowRez = BokehPrereqs (_MainTex, i.uv1, fromOriginal, _Threshhold.z);
- half4 outColor = half4(0,0,0, fromOriginal.a);
- half modulate = fromOriginal.a;
-
- // this code imitates the if-then-else conditions below
- half2 conditionCheck = half2( dot(abs(fromOriginal.rgb-lowRez.rgb), half3(0.3,0.5,0.2)), Luminance(fromOriginal.rgb));
- conditionCheck *= fromOriginal.a;
- conditionCheck = saturate(_Threshhold.xy - conditionCheck);
- outColor = lerp (outColor, fromOriginal, saturate (dot(conditionCheck, half2(1000.0,1000.0))));
-
- /*
- if ( abs(dot(fromOriginal.rgb - lowRez.rgb, half3 (0.3,0.5,0.2))) * modulate < _Threshhold.x)
- outColor = fromOriginal; // no darkening
- if (Luminance(fromOriginal.rgb) * modulate < _Threshhold.y)
- outColor = fromOriginal; // no darkening
- if (lowRez.a < _Threshhold.z) // need to make foreground not cast false bokeh's
- outColor = fromOriginal; // no darkenin
- */
-
- return outColor;
- }
-
- half4 fragExtractAndAddToBokeh (v2fRadius i) : SV_Target {
- half4 from = tex2D(_MainTex, i.uv.xy);
- half4 lowRez = BokehPrereqs(_MainTex, i.uv1, from, _Threshhold.z);
- half4 outColor = from;
- // this code imitates the if-then-else conditions below
- half2 conditionCheck = half2( dot(abs(from.rgb-lowRez.rgb), half3(0.3,0.5,0.2)), Luminance(from.rgb));
- conditionCheck *= from.a;
- conditionCheck = saturate(_Threshhold.xy - conditionCheck);
- outColor = lerp (outColor, half4(0,0,0,0), saturate (dot(conditionCheck, half2(1000.0,1000.0))));
-
- /*
- if ( abs(dot(from.rgb - lowRez.rgb, half3 (0.3,0.5,0.2))) * modulate < _Threshhold.x)
- outColor = half4(0,0,0,0); // don't add
- if (Luminance(from.rgb) * modulate < _Threshhold.y)
- outColor = half4(0,0,0,0); // don't add
- if (lowRez.a < _Threshhold.z) // need to make foreground not cast false bokeh's
- outColor = half4(0,0,0,0); // don't add
- */
-
- return outColor;
- }
-
- ENDCG
-
- Subshader {
-
- // pass 0
-
- Pass {
- ZTest Always Cull Off ZWrite Off
- CGPROGRAM
- #pragma vertex vertDofApply
- #pragma fragment fragDofApplyBg
-
- ENDCG
- }
- // pass 1
-
- Pass {
- ZTest Always Cull Off ZWrite Off
- ColorMask RGB
- CGPROGRAM
- #pragma vertex vertDofApply
- #pragma fragment fragDofApplyFgDebug
- ENDCG
- }
- // pass 2
- Pass {
- ZTest Always Cull Off ZWrite Off
- ColorMask RGB
- CGPROGRAM
- #pragma vertex vertDofApply
- #pragma fragment fragDofApplyBgDebug
- ENDCG
- }
-
-
-
- // pass 3
-
- Pass {
- ZTest Always Cull Off ZWrite Off
- ColorMask A
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment fragCocBg
- ENDCG
- }
-
-
- // pass 4
-
- Pass {
- ZTest Always Cull Off ZWrite Off
- ColorMask RGB
- //Blend One One
- CGPROGRAM
- #pragma vertex vertDofApply
- #pragma fragment fragDofApplyFg
-
- ENDCG
- }
- // pass 5
-
- Pass {
- ZTest Always Cull Off ZWrite Off
- ColorMask ARGB
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment fragCocFg
- ENDCG
- }
- // pass 6
-
- Pass {
- ZTest Always Cull Off ZWrite Off
- CGPROGRAM
- #pragma vertex vertDownsampleWithCocConserve
- #pragma fragment fragDownsampleWithCocConserve
- ENDCG
- }
- // pass 7
- // not being used atm
-
- Pass {
- ZTest Always Cull Off ZWrite Off
- ColorMask RGBA
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment fragMask
- ENDCG
- }
- // pass 8
-
- Pass {
- ZTest Always Cull Off ZWrite Off
- Blend SrcAlpha OneMinusSrcAlpha
- ColorMask RGB
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment fragAddBokeh
- ENDCG
- }
-
- // pass 9
-
- Pass {
- ZTest Always Cull Off ZWrite Off
- Blend One One
- ColorMask RGB
- CGPROGRAM
- #pragma vertex vertWithRadius
- #pragma fragment fragExtractAndAddToBokeh
- ENDCG
- }
-
- // pass 10
-
- Pass {
- ZTest Always Cull Off ZWrite Off
- CGPROGRAM
- #pragma vertex vertWithRadius
- #pragma fragment fragDarkenForBokeh
- ENDCG
- }
-
- // pass 11
-
- Pass {
- ZTest Always Cull Off ZWrite Off
- CGPROGRAM
- #pragma vertex vertWithRadius
- #pragma fragment fragExtractAndAddToBokeh
- ENDCG
- }
- }
-
- Fallback off
- }
|