123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- #ifndef __DEPTH_OF_FIELD__
- #define __DEPTH_OF_FIELD__
- #if SHADER_TARGET >= 50
-
- #define SEPARATE_TEXTURE_SAMPLER
- #define DOF_DECL_TEX2D(tex) Texture2D tex; SamplerState sampler##tex
- #define DOF_TEX2D(tex, coord) tex.Sample(sampler##tex, coord)
- #else
- #define DOF_DECL_TEX2D(tex) sampler2D tex
- #define DOF_TEX2D(tex, coord) tex2D(tex, coord)
- #endif
- #include "Common.cginc"
- #include "DiskKernels.cginc"
- DOF_DECL_TEX2D(_CameraDepthTexture);
- DOF_DECL_TEX2D(_CameraMotionVectorsTexture);
- DOF_DECL_TEX2D(_CoCTex);
- float _Distance;
- float _LensCoeff;
- float _MaxCoC;
- float _RcpMaxCoC;
- float _RcpAspect;
- half3 _TaaParams;
- struct VaryingsDOF
- {
- float4 pos : SV_POSITION;
- half2 uv : TEXCOORD0;
- half2 uvAlt : TEXCOORD1;
- };
- VaryingsDOF VertDOF(AttributesDefault v)
- {
- half2 uvAlt = v.texcoord;
- #if UNITY_UV_STARTS_AT_TOP
- if (_MainTex_TexelSize.y < 0.0) uvAlt.y = 1.0 - uvAlt.y;
- #endif
- VaryingsDOF o;
- o.pos = UnityObjectToClipPos(v.vertex);
- #if defined(UNITY_SINGLE_PASS_STEREO)
- o.uv = UnityStereoScreenSpaceUVAdjust(v.texcoord, _MainTex_ST);
- o.uvAlt = UnityStereoScreenSpaceUVAdjust(uvAlt, _MainTex_ST);
- #else
- o.uv = v.texcoord;
- o.uvAlt = uvAlt;
- #endif
- return o;
- }
- half4 FragCoC(VaryingsDOF i) : SV_Target
- {
- float depth = LinearEyeDepth(DOF_TEX2D(_CameraDepthTexture, i.uv));
- half coc = (depth - _Distance) * _LensCoeff / max(depth, 1e-5);
- return saturate(coc * 0.5 * _RcpMaxCoC + 0.5);
- }
- half4 FragTempFilter(VaryingsDOF i) : SV_Target
- {
- float3 uvOffs = _MainTex_TexelSize.xyy * float3(1, 1, 0);
- #if defined(SEPARATE_TEXTURE_SAMPLER)
- half4 cocTL = _CoCTex.GatherRed(sampler_CoCTex, i.uv - uvOffs.xy * 0.5);
- half4 cocBR = _CoCTex.GatherRed(sampler_CoCTex, i.uv + uvOffs.xy * 0.5);
- half coc1 = cocTL.x;
- half coc2 = cocTL.z;
- half coc3 = cocBR.x;
- half coc4 = cocBR.z;
- #else
- half coc1 = DOF_TEX2D(_CoCTex, i.uv - uvOffs.xz).r;
- half coc2 = DOF_TEX2D(_CoCTex, i.uv - uvOffs.zy).r;
- half coc3 = DOF_TEX2D(_CoCTex, i.uv + uvOffs.zy).r;
- half coc4 = DOF_TEX2D(_CoCTex, i.uv + uvOffs.xz).r;
- #endif
-
- half coc0 = DOF_TEX2D(_CoCTex, i.uv - _TaaParams.xy).r;
-
- float3 closest = float3(0, 0, coc0);
- closest = coc1 < closest.z ? float3(-uvOffs.xz, coc1) : closest;
- closest = coc2 < closest.z ? float3(-uvOffs.zy, coc2) : closest;
- closest = coc3 < closest.z ? float3(+uvOffs.zy, coc3) : closest;
- closest = coc4 < closest.z ? float3(+uvOffs.xz, coc4) : closest;
-
- float2 motion = DOF_TEX2D(_CameraMotionVectorsTexture, i.uv + closest.xy).xy;
- half cocHis = DOF_TEX2D(_MainTex, i.uv - motion).r;
-
- half cocMin = closest.z;
- half cocMax = max(max(max(max(coc0, coc1), coc2), coc3), coc4);
- cocHis = clamp(cocHis, cocMin, cocMax);
-
- return lerp(coc0, cocHis, _TaaParams.z);
- }
- half4 FragPrefilter(VaryingsDOF i) : SV_Target
- {
- #if defined(SEPARATE_TEXTURE_SAMPLER)
-
- half4 c_r = _MainTex.GatherRed (sampler_MainTex, i.uv);
- half4 c_g = _MainTex.GatherGreen(sampler_MainTex, i.uv);
- half4 c_b = _MainTex.GatherBlue (sampler_MainTex, i.uv);
- half3 c0 = half3(c_r.x, c_g.x, c_b.x);
- half3 c1 = half3(c_r.y, c_g.y, c_b.y);
- half3 c2 = half3(c_r.z, c_g.z, c_b.z);
- half3 c3 = half3(c_r.w, c_g.w, c_b.w);
-
- half4 cocs = _CoCTex.Gather(sampler_CoCTex, i.uvAlt) * 2.0 - 1.0;
- half coc0 = cocs.x;
- half coc1 = cocs.y;
- half coc2 = cocs.z;
- half coc3 = cocs.w;
- #else
- float3 duv = _MainTex_TexelSize.xyx * float3(0.5, 0.5, -0.5);
-
- half3 c0 = DOF_TEX2D(_MainTex, i.uv - duv.xy).rgb;
- half3 c1 = DOF_TEX2D(_MainTex, i.uv - duv.zy).rgb;
- half3 c2 = DOF_TEX2D(_MainTex, i.uv + duv.zy).rgb;
- half3 c3 = DOF_TEX2D(_MainTex, i.uv + duv.xy).rgb;
-
- half coc0 = DOF_TEX2D(_CoCTex, i.uvAlt - duv.xy).r * 2.0 - 1.0;
- half coc1 = DOF_TEX2D(_CoCTex, i.uvAlt - duv.zy).r * 2.0 - 1.0;
- half coc2 = DOF_TEX2D(_CoCTex, i.uvAlt + duv.zy).r * 2.0 - 1.0;
- half coc3 = DOF_TEX2D(_CoCTex, i.uvAlt + duv.xy).r * 2.0 - 1.0;
- #endif
-
- float w0 = abs(coc0) / (Max3(c0) + 1.0);
- float w1 = abs(coc1) / (Max3(c1) + 1.0);
- float w2 = abs(coc2) / (Max3(c2) + 1.0);
- float w3 = abs(coc3) / (Max3(c3) + 1.0);
-
- half3 avg = c0 * w0 + c1 * w1 + c2 * w2 + c3 * w3;
- avg /= max(w0 + w1 + w2 + w3, 1e-5);
-
- half coc_min = Min4(coc0, coc1, coc2, coc3);
- half coc_max = Max4(coc0, coc1, coc2, coc3);
- half coc = (-coc_min > coc_max ? coc_min : coc_max) * _MaxCoC;
-
- avg *= smoothstep(0, _MainTex_TexelSize.y * 2, abs(coc));
- #if defined(UNITY_COLORSPACE_GAMMA)
- avg = GammaToLinearSpace(avg);
- #endif
- return half4(avg, coc);
- }
- half4 FragBlur(VaryingsDOF i) : SV_Target
- {
- half4 samp0 = DOF_TEX2D(_MainTex, i.uv);
- half4 bgAcc = 0.0;
- half4 fgAcc = 0.0;
- UNITY_LOOP for (int si = 0; si < kSampleCount; si++)
- {
- float2 disp = kDiskKernel[si] * _MaxCoC;
- float dist = length(disp);
- float2 duv = float2(disp.x * _RcpAspect, disp.y);
- half4 samp = DOF_TEX2D(_MainTex, i.uv + duv);
-
-
- half bgCoC = max(min(samp0.a, samp.a), 0.0);
-
-
- const half margin = _MainTex_TexelSize.y * 2;
- half bgWeight = saturate((bgCoC - dist + margin) / margin);
- half fgWeight = saturate((-samp.a - dist + margin) / margin);
-
-
- fgWeight *= step(_MainTex_TexelSize.y, -samp.a);
-
- bgAcc += half4(samp.rgb, 1.0) * bgWeight;
- fgAcc += half4(samp.rgb, 1.0) * fgWeight;
- }
-
- bgAcc.rgb /= bgAcc.a + (bgAcc.a == 0.0);
- fgAcc.rgb /= fgAcc.a + (fgAcc.a == 0.0);
-
-
- bgAcc.a = smoothstep(_MainTex_TexelSize.y, _MainTex_TexelSize.y * 2.0, samp0.a);
-
- fgAcc.a *= UNITY_PI / kSampleCount;
-
- half alpha = saturate(fgAcc.a);
- half3 rgb = lerp(bgAcc.rgb, fgAcc.rgb, alpha);
- return half4(rgb, alpha);
- }
- half4 FragPostBlur(VaryingsDOF i) : SV_Target
- {
-
- const float4 duv = _MainTex_TexelSize.xyxy * float4(0.5, 0.5, -0.5, 0);
- half4 acc;
- acc = DOF_TEX2D(_MainTex, i.uv - duv.xy);
- acc += DOF_TEX2D(_MainTex, i.uv - duv.zy);
- acc += DOF_TEX2D(_MainTex, i.uv + duv.zy);
- acc += DOF_TEX2D(_MainTex, i.uv + duv.xy);
- return acc / 4.0;
- }
- #endif
|