HairComputeSrgs.azsli 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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. //
  10. // Copyright (c) 2019 Advanced Micro Devices, Inc. All rights reserved.
  11. //
  12. // Permission is hereby granted, free of charge, to any person obtaining a copy
  13. // of this software and associated documentation files (the "Software"), to deal
  14. // in the Software without restriction, including without limitation the rights
  15. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  16. // copies of the Software, and to permit persons to whom the Software is
  17. // furnished to do so, subject to the following conditions:
  18. //
  19. // The above copyright notice and this permission notice shall be included in
  20. // all copies or substantial portions of the Software.
  21. //
  22. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  23. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  24. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  25. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  26. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  27. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  28. // THE SOFTWARE.
  29. //
  30. //------------------------------------------------------------------------------
  31. // File: HairComputeSrgs.azsli
  32. //
  33. // Declarations of SRGs used by the hair shaders.
  34. //------------------------------------------------------------------------------
  35. #pragma once
  36. #include <Atom/Features/SrgSemantics.azsli>
  37. // Whether bones are specified by dual quaternion.
  38. // This option is not currently functional.
  39. #define TRESSFX_DQ 0
  40. //! notice - the following constants need to match what appears in AMD_TressFX.h
  41. #define AMD_TRESSFX_MAX_HAIR_GROUP_RENDER 16
  42. #define AMD_TRESSFX_MAX_NUM_BONES 512
  43. #define CM_TO_METERS 1.0
  44. #define METERS_TO_CM 1.0
  45. //#define CM_TO_METERS 0.01
  46. //#define METERS_TO_CM 100.0
  47. // The following macro is not being used yet due to limitation of the C preprocessor
  48. // mcpp that creates a shader compilation fault not being able to extend the macro.
  49. #define BYTE_OFFSET(index,baseOffset) ((baseOffset >> 2) + (index << 2))
  50. //!------------------------------ SRG Structure --------------------------------
  51. //! Per pass SRG the holds the dynamic read-write buffer shared across all
  52. //! dispatches and draw calls and used as the memory pool for all the dynamic
  53. //! buffer that can change between passes due to the application of skinning,
  54. //! simulation and physics affect and read by the rendering shaders.
  55. ShaderResourceGroup PassSrg : SRG_PerPass
  56. {
  57. RWStructuredBuffer<int> m_skinnedHairSharedBuffer;
  58. }
  59. //!=============================================================================
  60. //!
  61. //! Per Instance Space 1 - Dynamic Buffers for Hair Skinning and Simulation
  62. //!
  63. //! ----------------------------------------------------------------------------
  64. struct StrandLevelData
  65. {
  66. float4 skinningQuat;
  67. float4 vspQuat;
  68. float4 vspTranslation;
  69. };
  70. //!------------------------------ SRG Structure --------------------------------
  71. //! Per instance/draw SRG representing dynamic read-write set of buffers
  72. //! that are unique per instance and are shared and changed between passes due
  73. //! to the application of skinning, simulation and physics affect.
  74. //! It is then also read by the rendering shaders.
  75. //! This Srg is NOT shared by the passes since it requires having barriers between
  76. //! both passes and draw calls, instead, all buffers are allocated from a single
  77. //! shared buffer (through BufferViews) and that buffer is then shared between
  78. //! the passes via the PerPass Srg frequency.
  79. ShaderResourceGroup HairDynamicDataSrg : SRG_PerObject // space 1 - per instance / object
  80. {
  81. RWBuffer<float4> m_hairVertexPositions;
  82. RWBuffer<float4> m_hairVertexPositionsPrev;
  83. RWBuffer<float4> m_hairVertexPositionsPrevPrev;
  84. RWBuffer<float4> m_hairVertexTangents;
  85. RWStructuredBuffer<StrandLevelData> m_strandLevelData;
  86. //! Per hair object offset to the start location of each buffer within
  87. //! 'm_skinnedHairSharedBuffer'. The offset is in bytes!
  88. uint m_positionBufferOffset;
  89. uint m_positionPrevBufferOffset;
  90. uint m_positionPrevPrevBufferOffset;
  91. uint m_tangentBufferOffset;
  92. uint m_strandLevelDataOffset;
  93. };
  94. //------------------------------------------------------------------------------
  95. // Allow for the code to run with minimal changes - skinning / simulation compute passes
  96. // Usage of per-instance buffer
  97. #define g_HairVertexPositions HairDynamicDataSrg::m_hairVertexPositions
  98. #define g_HairVertexPositionsPrev HairDynamicDataSrg::m_hairVertexPositionsPrev
  99. #define g_HairVertexPositionsPrevPrev HairDynamicDataSrg::m_hairVertexPositionsPrevPrev
  100. #define g_HairVertexTangents HairDynamicDataSrg::m_hairVertexTangents
  101. #define g_StrandLevelData HairDynamicDataSrg::m_strandLevelData
  102. //------------------------------------------------------------------------------
  103. float3 GetSharedVector3(int offset)
  104. {
  105. return float3(
  106. asfloat(PassSrg::m_skinnedHairSharedBuffer[offset]),
  107. asfloat(PassSrg::m_skinnedHairSharedBuffer[offset + 1]),
  108. asfloat(PassSrg::m_skinnedHairSharedBuffer[offset + 2])
  109. );// *CM_TO_METERS; // convert to meters when using
  110. }
  111. void SetSharedVector3(int offset, float3 pos)
  112. {
  113. // pos.xyz *= METERS_TO_CM; // convert to cm when storing
  114. PassSrg::m_skinnedHairSharedBuffer[offset] = asint(pos.x);
  115. PassSrg::m_skinnedHairSharedBuffer[offset+1] = asint(pos.y);
  116. PassSrg::m_skinnedHairSharedBuffer[offset+2] = asint(pos.z);
  117. }
  118. float4 GetSharedVector4(int offset)
  119. {
  120. return float4(
  121. float3(
  122. asfloat(PassSrg::m_skinnedHairSharedBuffer[offset]),
  123. asfloat(PassSrg::m_skinnedHairSharedBuffer[offset + 1]),
  124. asfloat(PassSrg::m_skinnedHairSharedBuffer[offset + 2])
  125. ),// * CM_TO_METERS, // convert to meters when using
  126. asfloat(PassSrg::m_skinnedHairSharedBuffer[offset + 3])
  127. );
  128. }
  129. void SetSharedVector4(int offset, float4 pos)
  130. {
  131. // pos.xyz *= METERS_TO_CM; // convert to cm when storing
  132. PassSrg::m_skinnedHairSharedBuffer[offset] = asint(pos.x);
  133. PassSrg::m_skinnedHairSharedBuffer[offset+1] = asint(pos.y);
  134. PassSrg::m_skinnedHairSharedBuffer[offset+2] = asint(pos.z);
  135. PassSrg::m_skinnedHairSharedBuffer[offset+3] = asint(pos.w);
  136. }
  137. //------------------------------------------------------------------------------
  138. //! Getter/setter of position / tangent in the global shared buffer based on the
  139. //! per-instance offset of the instance positions buffer within the global shared buffer
  140. void SetSharedPosition3(int vertexIndex, float3 position)
  141. {
  142. int vertexOffset = (HairDynamicDataSrg::m_positionBufferOffset >> 2) + (vertexIndex << 2);
  143. SetSharedVector3(vertexOffset, position);
  144. }
  145. void SetSharedPosition(int vertexIndex, float4 position)
  146. {
  147. int vertexOffset = (HairDynamicDataSrg::m_positionBufferOffset >> 2) + (vertexIndex << 2);
  148. SetSharedVector4(vertexOffset, position);
  149. }
  150. float4 GetSharedPosition(int vertexIndex)
  151. {
  152. int vertexOffset = (HairDynamicDataSrg::m_positionBufferOffset >> 2) + (vertexIndex << 2);
  153. return GetSharedVector4(vertexOffset);
  154. }
  155. void SetSharedPrevPosition(int vertexIndex, float4 position)
  156. {
  157. int vertexOffset = (HairDynamicDataSrg::m_positionPrevBufferOffset >> 2) + (vertexIndex << 2);
  158. SetSharedVector4(vertexOffset, position);
  159. }
  160. float4 GetSharedPrevPosition(int vertexIndex)
  161. {
  162. int vertexOffset = (HairDynamicDataSrg::m_positionPrevBufferOffset >> 2) + (vertexIndex << 2);
  163. return GetSharedVector4(vertexOffset);
  164. }
  165. void SetSharedPrevPrevPosition(int vertexIndex, float4 position)
  166. {
  167. int vertexOffset = (HairDynamicDataSrg::m_positionPrevPrevBufferOffset >> 2) + (vertexIndex << 2);
  168. SetSharedVector4(vertexOffset, position);
  169. }
  170. float4 GetSharedPrevPrevPosition(int vertexIndex)
  171. {
  172. int vertexOffset = (HairDynamicDataSrg::m_positionPrevPrevBufferOffset >> 2) + (vertexIndex << 2);
  173. return GetSharedVector4(vertexOffset);
  174. }
  175. void SetSharedTangent(int tangentIndex, float3 currentTangent)
  176. {
  177. int tangentOffset = (HairDynamicDataSrg::m_tangentBufferOffset >> 2) + (tangentIndex << 2);
  178. PassSrg::m_skinnedHairSharedBuffer[tangentOffset] = asint(currentTangent.x);
  179. PassSrg::m_skinnedHairSharedBuffer[tangentOffset+1] = asint(currentTangent.y);
  180. PassSrg::m_skinnedHairSharedBuffer[tangentOffset+2] = asint(currentTangent.z);
  181. }
  182. float3 GetSharedTangent(int tangentIndex)
  183. {
  184. int tangentOffset = (HairDynamicDataSrg::m_tangentBufferOffset >> 2) + (tangentIndex << 2);
  185. return float3(
  186. asfloat(PassSrg::m_skinnedHairSharedBuffer[tangentOffset]),
  187. asfloat(PassSrg::m_skinnedHairSharedBuffer[tangentOffset + 1]),
  188. asfloat(PassSrg::m_skinnedHairSharedBuffer[tangentOffset + 2])
  189. );
  190. }