experiments with fresnel and shadergraph
[WindSway-HDRP.git] / Library / PackageCache / com.unity.postprocessing@2.1.6 / PostProcessing / Shaders / Builtins / DepthOfField.hlsl
blob57c597fa97096a7e2de7f247bf04de295de4fc1a
1 #ifndef UNITY_POSTFX_DEPTH_OF_FIELD
2 #define UNITY_POSTFX_DEPTH_OF_FIELD
4 #include "../StdLib.hlsl"
5 #include "../Colors.hlsl"
6 #include "DiskKernels.hlsl"
8 TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
9 float4 _MainTex_TexelSize;
11 TEXTURE2D_SAMPLER2D(_CameraDepthTexture, sampler_CameraDepthTexture);
12 TEXTURE2D_SAMPLER2D(_CameraMotionVectorsTexture, sampler_CameraMotionVectorsTexture);
14 TEXTURE2D_SAMPLER2D(_CoCTex, sampler_CoCTex);
16 TEXTURE2D_SAMPLER2D(_DepthOfFieldTex, sampler_DepthOfFieldTex);
17 float4 _DepthOfFieldTex_TexelSize;
19 // Camera parameters
20 float _Distance;
21 float _LensCoeff;  // f^2 / (N * (S1 - f) * film_width * 2)
22 float _MaxCoC;
23 float _RcpMaxCoC;
24 float _RcpAspect;
25 half3 _TaaParams; // Jitter.x, Jitter.y, Blending
27 // CoC calculation
28 half4 FragCoC(VaryingsDefault i) : SV_Target
30     float depth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, i.texcoordStereo));
31     half coc = (depth - _Distance) * _LensCoeff / max(depth, 1e-5);
32     return saturate(coc * 0.5 * _RcpMaxCoC + 0.5);
35 // Temporal filter
36 half4 FragTempFilter(VaryingsDefault i) : SV_Target
38     float3 uvOffs = _MainTex_TexelSize.xyy * float3(1.0, 1.0, 0.0);
40 #if UNITY_GATHER_SUPPORTED
42     half4 cocTL = GATHER_RED_TEXTURE2D(_CoCTex, sampler_CoCTex, UnityStereoTransformScreenSpaceTex(i.texcoord - uvOffs.xy * 0.5)); // top-left
43     half4 cocBR = GATHER_RED_TEXTURE2D(_CoCTex, sampler_CoCTex, UnityStereoTransformScreenSpaceTex(i.texcoord + uvOffs.xy * 0.5)); // bottom-right
44     half coc1 = cocTL.x; // top
45     half coc2 = cocTL.z; // left
46     half coc3 = cocBR.x; // bottom
47     half coc4 = cocBR.z; // right
49 #else
51     half coc1 = SAMPLE_TEXTURE2D(_CoCTex, sampler_CoCTex, UnityStereoTransformScreenSpaceTex(i.texcoord - uvOffs.xz)).r; // top
52     half coc2 = SAMPLE_TEXTURE2D(_CoCTex, sampler_CoCTex, UnityStereoTransformScreenSpaceTex(i.texcoord - uvOffs.zy)).r; // left
53     half coc3 = SAMPLE_TEXTURE2D(_CoCTex, sampler_CoCTex, UnityStereoTransformScreenSpaceTex(i.texcoord + uvOffs.zy)).r; // bottom
54     half coc4 = SAMPLE_TEXTURE2D(_CoCTex, sampler_CoCTex, UnityStereoTransformScreenSpaceTex(i.texcoord + uvOffs.xz)).r; // right
56 #endif
58     // Dejittered center sample.
59     half coc0 = SAMPLE_TEXTURE2D(_CoCTex, sampler_CoCTex, UnityStereoTransformScreenSpaceTex(i.texcoord - _TaaParams.xy)).r;
61     // CoC dilation: determine the closest point in the four neighbors
62     float3 closest = float3(0.0, 0.0, coc0);
63     closest = coc1 < closest.z ? float3(-uvOffs.xz, coc1) : closest;
64     closest = coc2 < closest.z ? float3(-uvOffs.zy, coc2) : closest;
65     closest = coc3 < closest.z ? float3( uvOffs.zy, coc3) : closest;
66     closest = coc4 < closest.z ? float3( uvOffs.xz, coc4) : closest;
68     // Sample the history buffer with the motion vector at the closest point
69     float2 motion = SAMPLE_TEXTURE2D(_CameraMotionVectorsTexture, sampler_CameraMotionVectorsTexture, UnityStereoTransformScreenSpaceTex(i.texcoord + closest.xy)).xy;
70     half cocHis = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(i.texcoord - motion)).r;
72     // Neighborhood clamping
73     half cocMin = closest.z;
74     half cocMax = Max3(Max3(coc0, coc1, coc2), coc3, coc4);
75     cocHis = clamp(cocHis, cocMin, cocMax);
77     // Blend with the history
78     return lerp(coc0, cocHis, _TaaParams.z);
81 // Prefilter: downsampling and premultiplying
82 half4 FragPrefilter(VaryingsDefault i) : SV_Target
84 #if UNITY_GATHER_SUPPORTED
86     // Sample source colors
87     half4 c_r = GATHER_RED_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoordStereo);
88     half4 c_g = GATHER_GREEN_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoordStereo);
89     half4 c_b = GATHER_BLUE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoordStereo);
91     half3 c0 = half3(c_r.x, c_g.x, c_b.x);
92     half3 c1 = half3(c_r.y, c_g.y, c_b.y);
93     half3 c2 = half3(c_r.z, c_g.z, c_b.z);
94     half3 c3 = half3(c_r.w, c_g.w, c_b.w);
96     // Sample CoCs
97     half4 cocs = GATHER_TEXTURE2D(_CoCTex, sampler_CoCTex, i.texcoordStereo) * 2.0 - 1.0;
98     half coc0 = cocs.x;
99     half coc1 = cocs.y;
100     half coc2 = cocs.z;
101     half coc3 = cocs.w;
103 #else
105     float3 duv = _MainTex_TexelSize.xyx * float3(0.5, 0.5, -0.5);
106     float2 uv0 = UnityStereoTransformScreenSpaceTex(i.texcoord - duv.xy);
107     float2 uv1 = UnityStereoTransformScreenSpaceTex(i.texcoord - duv.zy);
108     float2 uv2 = UnityStereoTransformScreenSpaceTex(i.texcoord + duv.zy);
109     float2 uv3 = UnityStereoTransformScreenSpaceTex(i.texcoord + duv.xy);
111     // Sample source colors
112     half3 c0 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv0).rgb;
113     half3 c1 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv1).rgb;
114     half3 c2 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv2).rgb;
115     half3 c3 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv3).rgb;
117     // Sample CoCs
118     half coc0 = SAMPLE_TEXTURE2D(_CoCTex, sampler_CoCTex, uv0).r * 2.0 - 1.0;
119     half coc1 = SAMPLE_TEXTURE2D(_CoCTex, sampler_CoCTex, uv1).r * 2.0 - 1.0;
120     half coc2 = SAMPLE_TEXTURE2D(_CoCTex, sampler_CoCTex, uv2).r * 2.0 - 1.0;
121     half coc3 = SAMPLE_TEXTURE2D(_CoCTex, sampler_CoCTex, uv3).r * 2.0 - 1.0;
123 #endif
125     // Apply CoC and luma weights to reduce bleeding and flickering
126     float w0 = abs(coc0) / (Max3(c0.r, c0.g, c0.b) + 1.0);
127     float w1 = abs(coc1) / (Max3(c1.r, c1.g, c1.b) + 1.0);
128     float w2 = abs(coc2) / (Max3(c2.r, c2.g, c2.b) + 1.0);
129     float w3 = abs(coc3) / (Max3(c3.r, c3.g, c3.b) + 1.0);
131     // Weighted average of the color samples
132     half3 avg = c0 * w0 + c1 * w1 + c2 * w2 + c3 * w3;
133     avg /= max(w0 + w1 + w2 + w3, 1e-5);
135     // Select the largest CoC value
136     half coc_min = min(coc0, Min3(coc1, coc2, coc3));
137     half coc_max = max(coc0, Max3(coc1, coc2, coc3));
138     half coc = (-coc_min > coc_max ? coc_min : coc_max) * _MaxCoC;
140     // Premultiply CoC again
141     avg *= smoothstep(0, _MainTex_TexelSize.y * 2, abs(coc));
143 #if defined(UNITY_COLORSPACE_GAMMA)
144     avg = SRGBToLinear(avg);
145 #endif
147     return half4(avg, coc);
150 // Bokeh filter with disk-shaped kernels
151 half4 FragBlur(VaryingsDefault i) : SV_Target
153     half4 samp0 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoordStereo);
155     half4 bgAcc = 0.0; // Background: far field bokeh
156     half4 fgAcc = 0.0; // Foreground: near field bokeh
158     UNITY_LOOP
159     for (int si = 0; si < kSampleCount; si++)
160     {
161         float2 disp = kDiskKernel[si] * _MaxCoC;
162         float dist = length(disp);
164         float2 duv = float2(disp.x * _RcpAspect, disp.y);
165         half4 samp = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(i.texcoord + duv));
167         // BG: Compare CoC of the current sample and the center sample
168         // and select smaller one.
169         half bgCoC = max(min(samp0.a, samp.a), 0.0);
171         // Compare the CoC to the sample distance.
172         // Add a small margin to smooth out.
173         const half margin = _MainTex_TexelSize.y * 2;
174         half bgWeight = saturate((bgCoC   - dist + margin) / margin);
175         half fgWeight = saturate((-samp.a - dist + margin) / margin);
177         // Cut influence from focused areas because they're darkened by CoC
178         // premultiplying. This is only needed for near field.
179         fgWeight *= step(_MainTex_TexelSize.y, -samp.a);
181         // Accumulation
182         bgAcc += half4(samp.rgb, 1.0) * bgWeight;
183         fgAcc += half4(samp.rgb, 1.0) * fgWeight;
184     }
186     // Get the weighted average.
187     bgAcc.rgb /= bgAcc.a + (bgAcc.a == 0.0); // zero-div guard
188     fgAcc.rgb /= fgAcc.a + (fgAcc.a == 0.0);
190     // BG: Calculate the alpha value only based on the center CoC.
191     // This is a rather aggressive approximation but provides stable results.
192     bgAcc.a = smoothstep(_MainTex_TexelSize.y, _MainTex_TexelSize.y * 2.0, samp0.a);
194     // FG: Normalize the total of the weights.
195     fgAcc.a *= PI / kSampleCount;
197     // Alpha premultiplying
198     half alpha = saturate(fgAcc.a);
199     half3 rgb = lerp(bgAcc.rgb, fgAcc.rgb, alpha);
201     return half4(rgb, alpha);
204 // Postfilter blur
205 half4 FragPostBlur(VaryingsDefault i) : SV_Target
207     // 9 tap tent filter with 4 bilinear samples
208     const float4 duv = _MainTex_TexelSize.xyxy * float4(0.5, 0.5, -0.5, 0);
209     half4 acc;
210     acc  = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(i.texcoord - duv.xy));
211     acc += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(i.texcoord - duv.zy));
212     acc += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(i.texcoord + duv.zy));
213     acc += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(i.texcoord + duv.xy));
214     return acc / 4.0;
217 // Combine with source
218 half4 FragCombine(VaryingsDefault i) : SV_Target
220     half4 dof = SAMPLE_TEXTURE2D(_DepthOfFieldTex, sampler_DepthOfFieldTex, i.texcoordStereo);
221     half coc = SAMPLE_TEXTURE2D(_CoCTex, sampler_CoCTex, i.texcoordStereo).r;
222     coc = (coc - 0.5) * 2.0 * _MaxCoC;
224     // Convert CoC to far field alpha value.
225     float ffa = smoothstep(_MainTex_TexelSize.y * 2.0, _MainTex_TexelSize.y * 4.0, coc);
227     half4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoordStereo);
229 #if defined(UNITY_COLORSPACE_GAMMA)
230     color = SRGBToLinear(color);
231 #endif
233     half alpha = Max3(dof.r, dof.g, dof.b);
235     // lerp(lerp(color, dof, ffa), dof, dof.a)
236     color = lerp(color, float4(dof.rgb, alpha), ffa + dof.a - ffa * dof.a);
238 #if defined(UNITY_COLORSPACE_GAMMA)
239     color = LinearToSRGB(color);
240 #endif
242     return color;
245 // Debug overlay
246 half4 FragDebugOverlay(VaryingsDefault i) : SV_Target
248     half3 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoordStereo).rgb;
250     // Calculate the radiuses of CoC.
251     half4 src = SAMPLE_TEXTURE2D(_DepthOfFieldTex, sampler_DepthOfFieldTex, i.texcoordStereo);
252     float depth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, i.texcoordStereo));
253     float coc = (depth - _Distance) * _LensCoeff / depth;
254     coc *= 80;
256     // Visualize CoC (white -> red -> gray)
257     half3 rgb = lerp(half3(1.0, 0.0, 0.0), half3(1.0, 1.0, 1.0), saturate(-coc));
258     rgb = lerp(rgb, half3(0.4, 0.4, 0.4), saturate(coc));
260     // Black and white image overlay
261     rgb *= Luminance(color) + 0.5;
263     // Gamma correction
264 #if !UNITY_COLORSPACE_GAMMA
265     rgb = SRGBToLinear(rgb);
266 #endif
268     return half4(rgb, 1.0);
271 #endif // UNITY_POSTFX_DEPTH_OF_FIELD