HairShortCutGeometryDepthAlpha.azsl 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * Modifications 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. //
  9. // Copyright (c) 2019 Advanced Micro Devices, Inc. All rights reserved.
  10. //
  11. // Permission is hereby granted, free of charge, to any person obtaining a copy
  12. // of this software and associated documentation files (the "Software"), to deal
  13. // in the Software without restriction, including without limitation the rights
  14. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  15. // copies of the Software, and to permit persons to whom the Software is
  16. // furnished to do so, subject to the following conditions:
  17. //
  18. // The above copyright notice and this permission notice shall be included in
  19. // all copies or substantial portions of the Software.
  20. //
  21. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  22. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  23. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  24. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  25. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  26. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  27. // THE SOFTWARE.
  28. //
  29. #include <Atom/Features/SrgSemantics.azsli>
  30. #include <HairRenderingSrgs.azsli>
  31. //!------------------------------ SRG Structure --------------------------------
  32. //! Per pass SRG that holds the dynamic shared read-write buffer shared
  33. //! across all dispatches and draw calls. It is used for all the dynamic buffers
  34. //! that can change between passes due to the application of skinning, simulation
  35. //! and physics affect.
  36. //! Once the compute pases are done, it is read by the rendering shaders.
  37. ShaderResourceGroup PassSrg : SRG_PerPass_WithFallback
  38. {
  39. //! This shared buffer needs to match the SharedBuffer structure
  40. //! shared between all draw calls / dispatches for the hair skinning
  41. StructuredBuffer<int> m_skinnedHairSharedBuffer;
  42. //! Based on [[vk::binding(0, 3)]] RWTexture2DArray<uint> RWFragmentDepthsTexture : register(u0, space3);
  43. RWTexture2DArray<uint> m_RWFragmentDepthsTexture;
  44. }
  45. //==============================================================================
  46. //!------------------------------ SRG Structure --------------------------------
  47. //! Per instance/draw SRG representing dynamic read-write set of buffers
  48. //! that are unique per instance and are shared and changed between passes due
  49. //! to the application of skinning, simulation and physics affect.
  50. //! It is then also read by the rendering shaders.
  51. //! This Srg is NOT shared by the passes since it requires having barriers between
  52. //! both passes and draw calls, instead, all buffers are allocated from a single
  53. //! shared buffer (through BufferViews) and that buffer is then shared between
  54. //! the passes via the PerPass Srg frequency.
  55. ShaderResourceGroup HairDynamicDataSrg : SRG_PerObject // space 1 - per instance / object
  56. {
  57. Buffer<float4> m_hairVertexPositions;
  58. Buffer<float4> m_hairVertexTangents;
  59. //! Per hair object offset to the start location of each buffer within
  60. //! 'm_skinnedHairSharedBuffer'. The offset is in bytes!
  61. uint m_positionBufferOffset;
  62. uint m_tangentBufferOffset;
  63. };
  64. //------------------------------------------------------------------------------
  65. // Allow for the code to run with minimal changes - skinning / simulation compute passes
  66. // Usage of per-instance buffer
  67. #define g_GuideHairVertexPositions HairDynamicDataSrg::m_hairVertexPositions
  68. #define g_GuideHairVertexTangents HairDynamicDataSrg::m_hairVertexTangents
  69. //------------------------------------------------------------------------------
  70. #include <HairStrands.azsli> // VS resides here
  71. //!=============================================================================
  72. //! Geometry Depth Alpha - First Pass of ShortCut Render
  73. //! It is a Geometry pass that stores the K=3 front fragment depths, and accumulates
  74. //! product of 1-alpha multiplications (fade out) of the input render target.
  75. //!
  76. //! Short explanation: in the original AMD implementation 1-alpha is multiplied
  77. //! repeatedly with the incoming render target (back buffer) hence blending out
  78. //! the existing back buffer color based on the density and transparency of the hair.
  79. //! This implies that later on the hair color should be added based on the inverse
  80. //! of this operation.
  81. //!=============================================================================
  82. [earlydepthstencil]
  83. float HairShortCutDepthsAlphaPS(PS_INPUT_HAIR input) : SV_Target
  84. {
  85. //////////////////////////////////////////////////////////////////////
  86. // [To Do] Hair: anti aliasing via coverage requires work and is disabled for now
  87. // float3 vNDC = ScreenPosToNDC(PassSrg::m_linearDepth, input.Position.xy, input.Position.z);
  88. // uint2 dimensions;
  89. // PassSrg::m_linearDepth.GetDimensions(dimensions.x, dimensions.y);
  90. // float coverage = ComputeCoverage(input.p0p1.xy, input.p0p1.zw, vNDC.xy, float2(dimensions.x, dimensions.y));
  91. float coverage = 1.0;
  92. /////////////////////////////////////////////////////////////////////
  93. float alpha = coverage * MatBaseColor.a;
  94. if (alpha < SHORTCUT_MIN_ALPHA)
  95. return 1.0;
  96. int2 vScreenAddress = int2(input.Position.xy);
  97. uint uDepth = asuint(input.Position.z);
  98. uint uDepth0Prev, uDepth1Prev, uDepth2Prev;
  99. // Min of depth 0 and input depth - in Atom the Z order is reverse
  100. // Original value is uDepth0Prev
  101. InterlockedMax(PassSrg::m_RWFragmentDepthsTexture[uint3(vScreenAddress, 0)], uDepth, uDepth0Prev);
  102. // Min of depth 1 and greater of the last compare - in Atom the Z order is reverse
  103. // If fragment opaque, always use input depth (don't need greater depths)
  104. uDepth = (alpha > 0.98) ? uDepth : max(uDepth, uDepth0Prev);
  105. InterlockedMax(PassSrg::m_RWFragmentDepthsTexture[uint3(vScreenAddress, 1)], uDepth, uDepth1Prev);
  106. // Min of depth 2 and greater of the last compare - in Atom the Z order is reverse
  107. // If fragment opaque, always use input depth (don't need greater depths)
  108. uDepth = (alpha > 0.98) ? uDepth : max(uDepth, uDepth1Prev);
  109. InterlockedMax(PassSrg::m_RWFragmentDepthsTexture[uint3(vScreenAddress, 2)], uDepth, uDepth2Prev);
  110. // Accumulate the alpha multiplication from all hair components by multiplying the inverse and
  111. // therefore going down towards 0. At the end product, the inverse will be taken as the hair
  112. // alpha and the remainder will be used to blend the back buffer.
  113. return 1.0 - alpha;
  114. }