HairShortCutGeometryShading.azsl 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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. // Shader code related to lighting and shadowing for TressFX
  10. //------------------------------------------------------------------------------
  11. //
  12. // Copyright (c) 2019 Advanced Micro Devices, Inc. All rights reserved.
  13. //
  14. // Permission is hereby granted, free of charge, to any person obtaining a copy
  15. // of this software and associated documentation files (the "Software"), to deal
  16. // in the Software without restriction, including without limitation the rights
  17. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  18. // copies of the Software, and to permit persons to whom the Software is
  19. // furnished to do so, subject to the following conditions:
  20. //
  21. // The above copyright notice and this permission notice shall be included in
  22. // all copies or substantial portions of the Software.
  23. //
  24. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  25. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  26. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  27. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  28. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  29. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  30. // THE SOFTWARE.
  31. //
  32. #include <Atom/Features/SrgSemantics.azsli>
  33. #include <HairRenderingSrgs.azsli>
  34. #define AMD_TRESSFX_MAX_HAIR_GROUP_RENDER 16
  35. //!------------------------------ SRG Structure --------------------------------
  36. //! Per pass SRG that holds the dynamic shared read-write buffer shared
  37. //! across all dispatches and draw calls. It is used for all the dynamic buffers
  38. //! that can change between passes due to the application of skinning, simulation
  39. //! and physics affect.
  40. //! Once the compute pases are done, it is read by the rendering shaders.
  41. ShaderResourceGroup PassSrg : SRG_PerPass_WithFallback
  42. {
  43. //! This shared buffer needs to match the SharedBuffer structure
  44. //! shared between all draw calls / dispatches for the hair skinning
  45. StructuredBuffer<int> m_skinnedHairSharedBuffer;
  46. //! Per hair object material array used by the PPLL resolve pass
  47. //! Originally in TressFXRendering.hlsl this is space 0
  48. HairObjectShadeParams m_hairParams[AMD_TRESSFX_MAX_HAIR_GROUP_RENDER];
  49. // Will be used as thickness indication to block TT (back) lobe
  50. Texture2D<float> m_accumInvAlpha;
  51. // Linear depth is used for getting the screen to world transform
  52. Texture2D<float> m_linearDepth;
  53. //------------------------------
  54. // Lighting Data
  55. //------------------------------
  56. Sampler LinearSampler
  57. { // Required by LightingData.azsli
  58. MinFilter = Linear;
  59. MagFilter = Linear;
  60. MipFilter = Linear;
  61. AddressU = Clamp;
  62. AddressV = Clamp;
  63. AddressW = Clamp;
  64. };
  65. Sampler PointSampler
  66. { // Required by LightingData.azsli
  67. MinFilter = Point;
  68. MagFilter = Point;
  69. MipFilter = Point;
  70. AddressU = Clamp;
  71. AddressV = Clamp;
  72. AddressW = Clamp;
  73. };
  74. Texture2DArray<float> m_directionalLightShadowmap;
  75. Texture2DArray<float> m_directionalLightExponentialShadowmap;
  76. Texture2DArray<float> m_projectedShadowmaps;
  77. Texture2DArray<float> m_projectedExponentialShadowmap;
  78. Texture2D m_brdfMap;
  79. Texture2D<uint4> m_tileLightData;
  80. StructuredBuffer<uint> m_lightListRemapped;
  81. Texture2D<float> m_fullscreenShadow;
  82. }
  83. //------------------------------------------------------------------------------
  84. //! The hair objects' material array buffer used by the rendering resolve pass
  85. #define HairParams PassSrg::m_hairParams
  86. //==============================================================================
  87. //!------------------------------ SRG Structure --------------------------------
  88. //! Per instance/draw SRG representing dynamic read-write set of buffers
  89. //! that are unique per instance and are shared and changed between passes due
  90. //! to the application of skinning, simulation and physics affect.
  91. //! It is then also read by the rendering shaders.
  92. //! This Srg is NOT shared by the passes since it requires having barriers between
  93. //! both passes and draw calls, instead, all buffers are allocated from a single
  94. //! shared buffer (through BufferViews) and that buffer is then shared between
  95. //! the passes via the PerPass Srg frequency.
  96. ShaderResourceGroup HairDynamicDataSrg : SRG_PerObject // space 1 - per instance / object
  97. {
  98. Buffer<float4> m_hairVertexPositions;
  99. Buffer<float4> m_hairVertexTangents;
  100. //! Per hair object offset to the start location of each buffer within
  101. //! 'm_skinnedHairSharedBuffer'. The offset is in bytes!
  102. uint m_positionBufferOffset;
  103. uint m_tangentBufferOffset;
  104. };
  105. //------------------------------------------------------------------------------
  106. // Allow for the code to run with minimal changes - skinning / simulation compute passes
  107. // Usage of per-instance buffer
  108. #define g_GuideHairVertexPositions HairDynamicDataSrg::m_hairVertexPositions
  109. #define g_GuideHairVertexTangents HairDynamicDataSrg::m_hairVertexTangents
  110. //------------------------------------------------------------------------------
  111. #include <HairStrands.azsli> // VS resides here
  112. #include <HairFullScreenUtils.azsli> // Required for world coordinates calculation
  113. #include <HairLighting.azsli>
  114. //!=============================================================================
  115. //! Geometry Shading - Third Pass of ShortCut Render
  116. //! Geometry pass that shades pixels that passes the early depth test. Due to this, it
  117. //! is limited to the stored K near fragments due to previous depth write pass that
  118. //! wrote the furthest depth of the K stored depths.
  119. //! Colors are accumulated in the render target for a weighted average in final pass.
  120. //! [To Do] - in the original short cut, the alpha is taken from the depth alpha pass
  121. //!=============================================================================
  122. [earlydepthstencil]
  123. float4 HairShortCutGeometryColorPS(PS_INPUT_HAIR input) : SV_Target
  124. {
  125. // Strand Color read in is either the BaseMatColor, or BaseMatColor modulated with a color read from texture
  126. // on vertex shader for base color along with modulation by the tip color
  127. float4 strandColor = float4(input.StrandColor.rgb, MatBaseColor.a);
  128. // If we are supporting strand UV texturing, further blend in the texture color/alpha
  129. // Do this while computing NDC and coverage to hide latency from texture lookup
  130. if (EnableStrandUV)
  131. {
  132. // Grab the uv in case we need it
  133. float2 uv = float2(input.Tangent.w, input.StrandColor.w);
  134. // Apply StrandUVTiling
  135. float2 strandUV = float2(uv.x, (uv.y * StrandUVTilingFactor) - floor(uv.y * StrandUVTilingFactor));
  136. strandColor.rgb *= StrandAlbedoTexture.Sample(LinearWrapSampler, strandUV).rgb;
  137. }
  138. //////////////////////////////////////////////////////////////////////
  139. // [To Do] Hair: anti aliasing via coverage requires work and is disabled for now
  140. // float3 vNDC = ScreenPosToNDC(PassSrg::m_linearDepth, input.Position.xy, input.Position.z);
  141. // uint2 dimensions;
  142. // PassSrg::m_linearDepth.GetDimensions(dimensions.x, dimensions.y);
  143. // float2 screenCoords = saturate(pixelCoord / dimensions.xy);
  144. // float coverage = ComputeCoverage(input.p0p1.xy, input.p0p1.zw, vNDC.xy, float2(dimensions.x, dimensions.y));
  145. // original: float coverage = ComputeCoverage(input.p0p1.xy, input.p0p1.zw, vNDC.xy, g_vViewport.zw - g_vViewport.xy);
  146. float coverage = 1.0;
  147. /////////////////////////////////////////////////////////////////////
  148. float alpha = coverage;
  149. // Update the alpha to have proper value (accounting for coverage, base alpha, and strand alpha)
  150. alpha *= strandColor.w;
  151. // Early out
  152. if (alpha < SHORTCUT_MIN_ALPHA)
  153. {
  154. return float4(0, 0, 0, 0);
  155. }
  156. float2 pixelCoord = input.Position.xy;
  157. float depth = input.Position.z;
  158. // The following is a quick correction to remove the TT lobe (back lobe) contribution in case
  159. // the hair is thick. We do that by accumulating alpha from the hair for the blend operation
  160. // and this can be used here as an indication of thickness.
  161. float thickness = saturate(1.0 - PassSrg::m_accumInvAlpha[int2(pixelCoord)]);
  162. float3 shadedFragment = TressFXShading(pixelCoord, depth, input.Tangent.xyz, strandColor.rgb, thickness, RenderParamsIndex);
  163. // Color channel: Pre-multiply with alpha to create non-normalized weighted sum.
  164. // Alpha Channel: Sum up all the hair alphas - this will be used to normalize the color
  165. // per fragment at the next pass.
  166. return float4(shadedFragment * alpha, alpha);
  167. }