NewDepthOfFieldDownsample.azsl 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <Atom/Features/PostProcessing/FullscreenPixelInfo.azsli>
  9. #include <Atom/Features/PostProcessing/FullscreenVertex.azsli>
  10. #include <Atom/RPI/Math.azsli>
  11. #include "NewDepthOfFieldCommon.azsli"
  12. #include "DepthOfField.azsli"
  13. #include <viewsrg_all.srgi>
  14. #define COC_EPSILON 0.0001
  15. ShaderResourceGroup PassSrg : SRG_PerPass
  16. {
  17. Texture2D<float4> m_colorTexture;
  18. Texture2D<float4> m_depth;
  19. // Texture dimensions. XY channels are width and height and ZW channels are 1 / width and 1 / height
  20. // Auto-filled by the pass system when "ShaderImageDimensionsConstant" is specified in the .pass file
  21. float4 m_inputDimensions;
  22. float4 m_outputDimensions;
  23. Sampler PointSampler
  24. {
  25. MinFilter = Point;
  26. MagFilter = Point;
  27. MipFilter = Point;
  28. AddressU = Clamp;
  29. AddressV = Clamp;
  30. AddressW = Clamp;
  31. };
  32. }
  33. PSOutput MainPS(VSOutput IN)
  34. {
  35. // Sampling positions
  36. float2 outputPixelPos = IN.m_position.xy;
  37. float2 inputPixelPos = outputPixelPos * 2.0f;
  38. float2 inputUV = inputPixelPos * PassSrg::m_inputDimensions.zw;
  39. // Gather Depth
  40. float4 depthGather = PassSrg::m_depth.Gather(PassSrg::PointSampler, inputUV);
  41. depthGather = InvertDepth(depthGather);
  42. // Calculate CoC (Circle of Confusion)
  43. float far = ViewSrg::m_dof.m_cameraParameters.x;
  44. float near = ViewSrg::m_dof.m_cameraParameters.y;
  45. float focusDistance = ViewSrg::m_dof.m_cameraParameters.z;
  46. float4 cocGather;
  47. cocGather.x = ConvertDofFactor(depthGather.x, far, near, focusDistance);
  48. cocGather.y = ConvertDofFactor(depthGather.y, far, near, focusDistance);
  49. cocGather.z = ConvertDofFactor(depthGather.z, far, near, focusDistance);
  50. cocGather.w = ConvertDofFactor(depthGather.w, far, near, focusDistance);
  51. // Clamp CoC
  52. cocGather = clamp(cocGather, -1.0f, 1.0f);
  53. // Weight samples by CoC to avoid in focus pixels bleeding into bokeh effect
  54. float4 weights = abs(cocGather) + COC_EPSILON;
  55. weights = weights / (weights.x + weights.y + weights.z + weights.w);
  56. PSOutput OUT;
  57. // Red
  58. float4 redGather = PassSrg::m_colorTexture.GatherRed(PassSrg::PointSampler, inputUV);
  59. OUT.m_color.r = dot(redGather, weights);
  60. // Green
  61. float4 greenGather = PassSrg::m_colorTexture.GatherGreen(PassSrg::PointSampler, inputUV);
  62. OUT.m_color.g = dot(greenGather, weights);
  63. // Blue
  64. float4 blueGather = PassSrg::m_colorTexture.GatherBlue(PassSrg::PointSampler, inputUV);
  65. OUT.m_color.b = dot(blueGather, weights);
  66. // CoC - Take the CoC with the maximum absolute value (note CoC can be negative) to get the fullest bokeh effect
  67. // The above weighting by CoC mitigates bokeh bleeding from taking the max CoC
  68. float coc = cocGather.x;
  69. coc = abs(coc) < abs(cocGather.y) ? cocGather.y : coc;
  70. coc = abs(coc) < abs(cocGather.z) ? cocGather.z : coc;
  71. coc = abs(coc) < abs(cocGather.w) ? cocGather.w : coc;
  72. // CoC weighting #2: we use linear sampling when we compute the CoC blur
  73. // This can lead to in focus pixels bleeding into the bokeh blur
  74. // Pre-multiply the color values by the CoC to avoid this type of bleeding
  75. // Because we then re-multiply by the CoC value after the linear sampling, we want to avoid coc values of 0
  76. // See http://advances.realtimerendering.com/s2013/Sousa_Graphics_Gems_CryENGINE3.pptx
  77. coc = abs(coc) > COC_EPSILON ? coc : -COC_EPSILON;
  78. OUT.m_color.rgb *= abs(coc);
  79. OUT.m_color.a = coc;
  80. return OUT;
  81. }