DiffuseProbeGridDownsample.azsl 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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 <scenesrg_all.srgi>
  9. #include <viewsrg_all.srgi>
  10. #include <Atom/Features/PostProcessing/FullscreenVertexUtil.azsli>
  11. #include <Atom/Features/PostProcessing/FullscreenVertexInfo.azsli>
  12. #include <Atom/RPI/Math.azsli>
  13. ShaderResourceGroup PassSrg : SRG_PerPass
  14. {
  15. Texture2DMS<float4> m_normal; // RGB10 = Normal (Encoded), A2 = Flags
  16. Texture2DMS<float> m_depth;
  17. Sampler LinearSampler
  18. {
  19. MinFilter = Linear;
  20. MagFilter = Linear;
  21. MipFilter = Linear;
  22. AddressU = Clamp;
  23. AddressV = Clamp;
  24. AddressW = Clamp;
  25. };
  26. // scale multiplier of the downsampled size to the fullscreen size (e.g., 4)
  27. uint m_outputImageScale;
  28. }
  29. // Vertex Shader
  30. VSOutput MainVS(VSInput input)
  31. {
  32. VSOutput OUT;
  33. float4 posTex = GetVertexPositionAndTexCoords(input.m_vertexID);
  34. OUT.m_texCoord = float2(posTex.z, posTex.w);
  35. OUT.m_position = float4(posTex.x, posTex.y, 0.0, 1.0);
  36. return OUT;
  37. }
  38. struct PSOutput
  39. {
  40. float m_depth : SV_Depth;
  41. float4 m_normal : SV_Target0;
  42. };
  43. // Pixel Shader
  44. PSOutput MainPS(VSOutput IN, in uint sampleIndex : SV_SampleIndex)
  45. {
  46. uint2 screenCoords = IN.m_position.xy * PassSrg::m_outputImageScale;
  47. float downsampledDepth = 0;
  48. float4 downsampledEncodedNormal;
  49. for (uint y = 0; y < PassSrg::m_outputImageScale; ++y)
  50. {
  51. for (uint x = 0; x < PassSrg::m_outputImageScale; ++x)
  52. {
  53. float depth = PassSrg::m_depth.Load(screenCoords + int2(x, y), sampleIndex).r;
  54. float4 encodedNormal = PassSrg::m_normal.Load(screenCoords + int2(x, y), sampleIndex);
  55. // take the closest depth sample to ensure we're getting the normal closest to the viewer
  56. // (larger depth value due to reverse depth)
  57. if (depth > downsampledDepth)
  58. {
  59. downsampledDepth = depth;
  60. downsampledEncodedNormal = encodedNormal;
  61. }
  62. }
  63. }
  64. float3 downsampledNormal = DecodeNormalSignedOctahedron(downsampledEncodedNormal.rgb);
  65. PSOutput OUT;
  66. OUT.m_depth = downsampledDepth;
  67. OUT.m_normal = float4(downsampledNormal * 0.5f + 0.5f, 0.0f);
  68. return OUT;
  69. }