SkinnedMeshVertexStreamProperties.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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 <SkinnedMesh/SkinnedMeshVertexStreamProperties.h>
  9. #include <Atom/RPI.Reflect/ResourcePoolAssetCreator.h>
  10. #include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
  11. #include <Atom/RPI.Public/Model/Model.h>
  12. #include <Atom/RHI/Factory.h>
  13. #include <AzCore/Math/PackedVector3.h>
  14. namespace AZ
  15. {
  16. namespace Render
  17. {
  18. SkinnedMeshVertexStreamProperties::SkinnedMeshVertexStreamProperties()
  19. {
  20. // Attributes of the input buffers used for skinning
  21. m_inputStreamInfo[static_cast<uint8_t>(SkinnedMeshInputVertexStreams::Position)] = SkinnedMeshVertexStreamInfo{
  22. RHI::Format::R32G32B32_FLOAT,
  23. sizeof(AZ::PackedVector3f),
  24. Name{"SkinnedMeshInputPositions"},
  25. Name{"m_sourcePositions"},
  26. RHI::ShaderSemantic{Name{"POSITION"}},
  27. false, // isOptional
  28. SkinnedMeshInputVertexStreams::Position
  29. };
  30. m_inputStreamInfo[static_cast<uint8_t>(SkinnedMeshInputVertexStreams::Normal)] = SkinnedMeshVertexStreamInfo{
  31. RHI::Format::R32G32B32_FLOAT,
  32. sizeof(AZ::PackedVector3f),
  33. Name{"SkinnedMeshInputNormals"},
  34. Name{"m_sourceNormals"},
  35. RHI::ShaderSemantic{Name{"NORMAL"}},
  36. false, // isOptional
  37. SkinnedMeshInputVertexStreams::Normal
  38. };
  39. m_inputStreamInfo[static_cast<uint8_t>(SkinnedMeshInputVertexStreams::Tangent)] = SkinnedMeshVertexStreamInfo{
  40. RHI::Format::R32G32B32A32_FLOAT,
  41. sizeof(AZ::Vector4),
  42. Name{"SkinnedMeshInputTangents"},
  43. Name{"m_sourceTangents"},
  44. RHI::ShaderSemantic{Name{"TANGENT"}},
  45. false, // isOptional
  46. SkinnedMeshInputVertexStreams::Tangent
  47. };
  48. m_inputStreamInfo[static_cast<uint8_t>(SkinnedMeshInputVertexStreams::BiTangent)] = SkinnedMeshVertexStreamInfo{
  49. RHI::Format::R32G32B32_FLOAT,
  50. sizeof(AZ::PackedVector3f),
  51. Name{"SkinnedMeshInputBiTangents"},
  52. Name{"m_sourceBiTangents"},
  53. RHI::ShaderSemantic{Name{"BITANGENT"}},
  54. false, // isOptional
  55. SkinnedMeshInputVertexStreams::BiTangent
  56. };
  57. m_inputStreamInfo[static_cast<uint8_t>(SkinnedMeshInputVertexStreams::BlendIndices)] = SkinnedMeshVertexStreamInfo{
  58. RHI::Format::R32_UINT,
  59. sizeof(AZ::Vector4),
  60. Name{"SkinnedMeshInputBlendIndices"},
  61. Name{"m_sourceBlendIndices"},
  62. RHI::ShaderSemantic{Name{"SKIN_JOINTINDICES"}},
  63. false, // isOptional
  64. SkinnedMeshInputVertexStreams::BlendIndices
  65. };
  66. m_inputStreamInfo[static_cast<uint8_t>(SkinnedMeshInputVertexStreams::BlendWeights)] = SkinnedMeshVertexStreamInfo{
  67. RHI::Format::R32_FLOAT,
  68. sizeof(AZ::Vector4),
  69. Name{"SkinnedMeshInputBlendWeights"},
  70. Name{"m_sourceBlendWeights"},
  71. RHI::ShaderSemantic{Name{"SKIN_WEIGHTS"}},
  72. false, // isOptional
  73. SkinnedMeshInputVertexStreams::BlendWeights
  74. };
  75. // Attributes of the vertex buffers that are not used or modified during skinning, but are shared between all target models that share the same source
  76. m_staticStreamInfo[static_cast<uint8_t>(SkinnedMeshStaticVertexStreams::UV_0)] = SkinnedMeshVertexStreamInfo{
  77. RHI::Format::R32G32_FLOAT,
  78. sizeof(float[2]),
  79. Name{"SkinnedMeshStaticUVs"},
  80. Name{"unused"},
  81. RHI::ShaderSemantic{Name{"UV"}}
  82. };
  83. // Attributes of the vertex streams of the target model that is written to during skinning
  84. m_outputStreamInfo[static_cast<uint8_t>(SkinnedMeshOutputVertexStreams::Position)] = SkinnedMeshOutputVertexStreamInfo{
  85. RHI::Format::R32G32B32_FLOAT,
  86. sizeof(AZ::PackedVector3f),
  87. Name{"SkinnedMeshOutputPositions"},
  88. Name{"m_targetPositions"},
  89. RHI::ShaderSemantic{Name{"POSITION"}},
  90. SkinnedMeshInputVertexStreams::Position
  91. };
  92. m_outputStreamInfo[static_cast<uint8_t>(SkinnedMeshOutputVertexStreams::Normal)] = SkinnedMeshOutputVertexStreamInfo{
  93. RHI::Format::R32G32B32_FLOAT,
  94. sizeof(AZ::PackedVector3f),
  95. Name{"SkinnedMeshOutputNormals"},
  96. Name{"m_targetNormals"},
  97. RHI::ShaderSemantic{Name{"NORMAL"}},
  98. SkinnedMeshInputVertexStreams::Normal
  99. };
  100. m_outputStreamInfo[static_cast<uint8_t>(SkinnedMeshOutputVertexStreams::Tangent)] = SkinnedMeshOutputVertexStreamInfo{
  101. RHI::Format::R32G32B32A32_FLOAT,
  102. sizeof(AZ::Vector4),
  103. Name{"SkinnedMeshOutputTangents"},
  104. Name{"m_targetTangents"},
  105. RHI::ShaderSemantic{Name{"TANGENT"}},
  106. SkinnedMeshInputVertexStreams::Tangent
  107. };
  108. m_outputStreamInfo[static_cast<uint8_t>(SkinnedMeshOutputVertexStreams::BiTangent)] = SkinnedMeshOutputVertexStreamInfo{
  109. RHI::Format::R32G32B32_FLOAT,
  110. sizeof(AZ::PackedVector3f),
  111. Name{"SkinnedMeshOutputBiTangents"},
  112. Name{"m_targetBiTangents"},
  113. RHI::ShaderSemantic{Name{"BITANGENT"}},
  114. SkinnedMeshInputVertexStreams::BiTangent
  115. };
  116. {
  117. auto bufferPoolDesc = AZStd::make_unique<RHI::BufferPoolDescriptor>();
  118. // Output buffers are both written to during skinning and used as input assembly buffers
  119. bufferPoolDesc->m_bindFlags = RHI::BufferBindFlags::InputAssembly | RHI::BufferBindFlags::ShaderReadWrite;
  120. bufferPoolDesc->m_heapMemoryLevel = RHI::HeapMemoryLevel::Device;
  121. RPI::ResourcePoolAssetCreator creator;
  122. creator.Begin(Uuid::CreateRandom());
  123. creator.SetPoolDescriptor(AZStd::move(bufferPoolDesc));
  124. creator.SetPoolName("SkinnedMeshOutputStreamPool");
  125. creator.End(m_outputStreamResourcePool);
  126. }
  127. // Set the required and optional input streams for the skinned mesh compute shader
  128. // in a ShaderInputContract for retrieving the streams from the model
  129. for (const SkinnedMeshVertexStreamInfo& inputStreamInfo : m_inputStreamInfo)
  130. {
  131. RPI::ShaderInputContract::StreamChannelInfo channelInfo;
  132. channelInfo.m_semantic = inputStreamInfo.m_semantic;
  133. channelInfo.m_isOptional = inputStreamInfo.m_isOptional;
  134. channelInfo.m_componentCount = RHI::GetFormatComponentCount(inputStreamInfo.m_elementFormat);
  135. m_computeShaderInputContract.m_streamChannels.push_back(channelInfo);
  136. }
  137. };
  138. const SkinnedMeshVertexStreamInfo* SkinnedMeshVertexStreamProperties::GetInputStreamInfo(const RHI::ShaderSemantic& shaderSemantic) const
  139. {
  140. auto FindVertexStreamInfo = [&shaderSemantic](const SkinnedMeshVertexStreamInfo& vertexStreamInfo)
  141. {
  142. return shaderSemantic == vertexStreamInfo.m_semantic;
  143. };
  144. if (auto foundIt = AZStd::find_if(m_inputStreamInfo.begin(), m_inputStreamInfo.end(), FindVertexStreamInfo);
  145. foundIt != m_inputStreamInfo.end())
  146. {
  147. return foundIt;
  148. }
  149. else
  150. {
  151. return nullptr;
  152. }
  153. }
  154. const SkinnedMeshVertexStreamInfo& SkinnedMeshVertexStreamProperties::GetInputStreamInfo(SkinnedMeshInputVertexStreams stream) const
  155. {
  156. return m_inputStreamInfo[static_cast<uint8_t>(stream)];
  157. }
  158. const SkinnedMeshVertexStreamInfo& SkinnedMeshVertexStreamProperties::GetStaticStreamInfo(SkinnedMeshStaticVertexStreams stream) const
  159. {
  160. return m_staticStreamInfo[static_cast<uint8_t>(stream)];
  161. }
  162. const SkinnedMeshOutputVertexStreamInfo* SkinnedMeshVertexStreamProperties::GetOutputStreamInfo(const RHI::ShaderSemantic& shaderSemantic) const
  163. {
  164. auto FindVertexStreamInfo = [&shaderSemantic](const SkinnedMeshOutputVertexStreamInfo& vertexStreamInfo)
  165. {
  166. return shaderSemantic == vertexStreamInfo.m_semantic;
  167. };
  168. if (auto foundIt = AZStd::find_if(m_outputStreamInfo.begin(), m_outputStreamInfo.end(), FindVertexStreamInfo);
  169. foundIt != m_outputStreamInfo.end())
  170. {
  171. return foundIt;
  172. }
  173. else
  174. {
  175. return nullptr;
  176. }
  177. }
  178. const SkinnedMeshOutputVertexStreamInfo& SkinnedMeshVertexStreamProperties::GetOutputStreamInfo(SkinnedMeshOutputVertexStreams stream) const
  179. {
  180. return m_outputStreamInfo[static_cast<uint8_t>(stream)];
  181. }
  182. Data::Asset<RPI::ResourcePoolAsset> SkinnedMeshVertexStreamProperties::GetOutputStreamResourcePool() const
  183. {
  184. return m_outputStreamResourcePool;
  185. }
  186. uint32_t SkinnedMeshVertexStreamProperties::GetMaxSupportedVertexCount() const
  187. {
  188. return aznumeric_cast<uint32_t>(std::numeric_limits<uint16_t>::max()) * aznumeric_cast<uint32_t>(std::numeric_limits<uint16_t>::max());
  189. }
  190. const RPI::ShaderInputContract& SkinnedMeshVertexStreamProperties::GetComputeShaderInputContract() const
  191. {
  192. return m_computeShaderInputContract;
  193. }
  194. }// namespace Render
  195. }// namespace AZ