GaussianDepthOfField.shader 8.5 KB

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