No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GaussianDepthOfField.shader 9.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. Shader "Hidden/Universal Render Pipeline/GaussianDepthOfField"
  2. {
  3. HLSLINCLUDE
  4. #pragma target 3.5
  5. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
  6. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Filtering.hlsl"
  7. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
  8. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
  9. #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
  10. TEXTURE2D_X(_ColorTexture);
  11. TEXTURE2D_X(_FullCoCTexture);
  12. TEXTURE2D_X(_HalfCoCTexture);
  13. float4 _SourceSize;
  14. float4 _DownSampleScaleFactor;
  15. float3 _CoCParams;
  16. #define FarStart _CoCParams.x
  17. #define FarEnd _CoCParams.y
  18. #define MaxRadius _CoCParams.z
  19. #define BLUR_KERNEL 0
  20. #if BLUR_KERNEL == 0
  21. // Offsets & coeffs for optimized separable bilinear 3-tap gaussian (5-tap equivalent)
  22. const static int kTapCount = 3;
  23. const static float kOffsets[] = {
  24. -1.33333333,
  25. 0.00000000,
  26. 1.33333333
  27. };
  28. const static half kCoeffs[] = {
  29. 0.35294118,
  30. 0.29411765,
  31. 0.35294118
  32. };
  33. #elif BLUR_KERNEL == 1
  34. // Offsets & coeffs for optimized separable bilinear 5-tap gaussian (9-tap equivalent)
  35. const static int kTapCount = 5;
  36. const static float kOffsets[] = {
  37. -3.23076923,
  38. -1.38461538,
  39. 0.00000000,
  40. 1.38461538,
  41. 3.23076923
  42. };
  43. const static half kCoeffs[] = {
  44. 0.07027027,
  45. 0.31621622,
  46. 0.22702703,
  47. 0.31621622,
  48. 0.07027027
  49. };
  50. #endif
  51. half FragCoC(Varyings input) : SV_Target
  52. {
  53. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  54. float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
  55. float depth = LOAD_TEXTURE2D_X(_CameraDepthTexture, _SourceSize.xy * uv).x;
  56. depth = LinearEyeDepth(depth, _ZBufferParams);
  57. half coc = (depth - FarStart) / (FarEnd - FarStart);
  58. return saturate(coc);
  59. }
  60. struct PrefilterOutput
  61. {
  62. half coc : SV_Target0;
  63. half4 color : SV_Target1;
  64. };
  65. PrefilterOutput FragPrefilter(Varyings input)
  66. {
  67. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  68. float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
  69. #if _HIGH_QUALITY_SAMPLING
  70. // Use a rotated grid to minimize artifacts coming from horizontal and vertical boundaries
  71. // "High Quality Antialiasing" [Lorach07]
  72. const int kCount = 5;
  73. const float2 kTaps[] = {
  74. float2( 0.0, 0.0),
  75. float2( 0.9, -0.4),
  76. float2(-0.9, 0.4),
  77. float2( 0.4, 0.9),
  78. float2(-0.4, -0.9)
  79. };
  80. half4 colorAcc = 0.0;
  81. half farCoCAcc = 0.0;
  82. UNITY_UNROLL
  83. for (int i = 0; i < kCount; i++)
  84. {
  85. float2 tapCoord = _SourceSize.zw * kTaps[i] + uv;
  86. half4 tapColor = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, tapCoord);
  87. half coc = SAMPLE_TEXTURE2D_X(_FullCoCTexture, sampler_LinearClamp, tapCoord).x;
  88. // Pre-multiply CoC to reduce bleeding of background blur on focused areas
  89. colorAcc += tapColor * coc;
  90. farCoCAcc += coc;
  91. }
  92. half4 color = colorAcc * rcp(kCount);
  93. half farCoC = farCoCAcc * rcp(kCount);
  94. #else
  95. // Bilinear sampling the coc is technically incorrect but we're aiming for speed here
  96. half farCoC = SAMPLE_TEXTURE2D_X(_FullCoCTexture, sampler_LinearClamp, uv).x;
  97. // Fast bilinear downscale of the source target and pre-multiply the CoC to reduce
  98. // bleeding of background blur on focused areas
  99. half4 color = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv);
  100. color *= farCoC;
  101. #endif
  102. PrefilterOutput o;
  103. o.coc = farCoC;
  104. #if _ENABLE_ALPHA_OUTPUT
  105. o.color = color;
  106. #else
  107. o.color = half4(color.xyz, 0);
  108. #endif
  109. return o;
  110. }
  111. half4 Blur(Varyings input, float2 dir, float premultiply)
  112. {
  113. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  114. float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
  115. // Use the center CoC as radius
  116. int2 positionSS = int2(_SourceSize.xy * _DownSampleScaleFactor.xy * uv);
  117. half samp0CoC = LOAD_TEXTURE2D_X(_HalfCoCTexture, positionSS).x;
  118. float2 offset = _SourceSize.zw * _DownSampleScaleFactor.zw * dir * samp0CoC * MaxRadius;
  119. half4 acc = 0.0;
  120. half accAlpha = 0.0;
  121. UNITY_UNROLL
  122. for (int i = 0; i < kTapCount; i++)
  123. {
  124. float2 sampCoord = uv + kOffsets[i] * offset;
  125. half sampCoC = SAMPLE_TEXTURE2D_X(_HalfCoCTexture, sampler_LinearClamp, sampCoord).x;
  126. half4 sampColor = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, sampCoord);
  127. // Weight & pre-multiply to limit bleeding on the focused area
  128. half weight = saturate(1.0 - (samp0CoC - sampCoC));
  129. acc += half4(sampColor.xyz, premultiply ? sampCoC : 1.0) * kCoeffs[i] * weight;
  130. #if _ENABLE_ALPHA_OUTPUT
  131. accAlpha += sampColor.a * kCoeffs[i] * weight;
  132. #endif
  133. }
  134. acc.xyz /= acc.w + 1e-4; // Zero-div guard
  135. #if _ENABLE_ALPHA_OUTPUT
  136. accAlpha /= acc.w + 1e-4; // Zero-div guard
  137. return half4(acc.xyz, accAlpha);
  138. #else
  139. return half4(acc.xyz, 1.0);
  140. #endif
  141. }
  142. half4 FragBlurH(Varyings input) : SV_Target
  143. {
  144. return Blur(input, float2(1.0, 0.0), 1.0);
  145. }
  146. half4 FragBlurV(Varyings input) : SV_Target
  147. {
  148. return Blur(input, float2(0.0, 1.0), 0.0);
  149. }
  150. half4 FragComposite(Varyings input) : SV_Target
  151. {
  152. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  153. float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
  154. half4 baseColor = LOAD_TEXTURE2D_X(_BlitTexture, _SourceSize.xy * uv);
  155. half coc = LOAD_TEXTURE2D_X(_FullCoCTexture, _SourceSize.xy * uv).x;
  156. #if _HIGH_QUALITY_SAMPLING
  157. half4 farColor = SampleTexture2DBicubic(TEXTURE2D_X_ARGS(_ColorTexture, sampler_LinearClamp), uv, _SourceSize * _DownSampleScaleFactor, 1.0, unity_StereoEyeIndex);
  158. #else
  159. half4 farColor = SAMPLE_TEXTURE2D_X(_ColorTexture, sampler_LinearClamp, uv);
  160. #endif
  161. half4 dstColor = 0.0;
  162. half dstAlpha = 1.0;
  163. UNITY_BRANCH
  164. if (coc > 0.0)
  165. {
  166. // Non-linear blend
  167. // "CryEngine 3 Graphics Gems" [Sousa13]
  168. half blend = sqrt(coc * TWO_PI);
  169. dstColor = farColor * saturate(blend);
  170. dstAlpha = saturate(1.0 - blend);
  171. }
  172. #if _ENABLE_ALPHA_OUTPUT
  173. half4 outColor = dstColor + baseColor * dstAlpha;
  174. // Preserve the original value of the pixels with zero alpha
  175. outColor.rgb = outColor.a > 0 ? outColor.rgb : baseColor.rgb;
  176. return outColor;
  177. #else
  178. return half4(dstColor.rgb + baseColor.rgb * dstAlpha, 1.0);
  179. #endif
  180. }
  181. ENDHLSL
  182. SubShader
  183. {
  184. Tags { "RenderPipeline" = "UniversalPipeline" }
  185. LOD 100
  186. ZTest Always ZWrite Off Cull Off
  187. Pass
  188. {
  189. Name "Gaussian Depth Of Field CoC"
  190. HLSLPROGRAM
  191. #pragma vertex Vert
  192. #pragma fragment FragCoC
  193. ENDHLSL
  194. }
  195. Pass
  196. {
  197. Name "Gaussian Depth Of Field Prefilter"
  198. HLSLPROGRAM
  199. #pragma vertex Vert
  200. #pragma fragment FragPrefilter
  201. #pragma multi_compile_local_fragment _ _HIGH_QUALITY_SAMPLING
  202. #pragma multi_compile_fragment _ _ENABLE_ALPHA_OUTPUT
  203. ENDHLSL
  204. }
  205. Pass
  206. {
  207. Name "Gaussian Depth Of Field Blur Horizontal"
  208. HLSLPROGRAM
  209. #pragma vertex Vert
  210. #pragma fragment FragBlurH
  211. #pragma multi_compile_fragment _ _ENABLE_ALPHA_OUTPUT
  212. ENDHLSL
  213. }
  214. Pass
  215. {
  216. Name "Gaussian Depth Of Field Blur Vertical"
  217. HLSLPROGRAM
  218. #pragma vertex Vert
  219. #pragma fragment FragBlurV
  220. #pragma multi_compile_fragment _ _ENABLE_ALPHA_OUTPUT
  221. ENDHLSL
  222. }
  223. Pass
  224. {
  225. Name "Gaussian Depth Of Field Composite"
  226. HLSLPROGRAM
  227. #pragma vertex Vert
  228. #pragma fragment FragComposite
  229. #pragma multi_compile_local_fragment _ _HIGH_QUALITY_SAMPLING
  230. #pragma multi_compile_fragment _ _ENABLE_ALPHA_OUTPUT
  231. ENDHLSL
  232. }
  233. }
  234. }