3
0

RayTracingFeatureProcessor.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  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. #pragma once
  9. #include <RayTracing/RayTracingResourceList.h>
  10. #include <RayTracing/RayTracingIndexList.h>
  11. #include <Atom/Feature/TransformService/TransformServiceFeatureProcessor.h>
  12. #include <Atom/RHI/RayTracingAccelerationStructure.h>
  13. #include <Atom/RHI/RayTracingBufferPools.h>
  14. #include <Atom/RHI/BufferView.h>
  15. #include <Atom/RHI/ImageView.h>
  16. #include <AzCore/Math/Color.h>
  17. #include <AzCore/Math/Transform.h>
  18. // this define specifies that the mesh buffers and material textures are stored in the Bindless Srg
  19. // Note1: The previous implementation using separate unbounded arrays is preserved since it demonstrates a TDR caused by
  20. // the RHI unbounded array allocation. This define and the previous codepath can be removed once the TDR is
  21. // investigated and resolved.
  22. // Note2: There are corresponding USE_BINDLESS_SRG defines in the RayTracingSceneSrg.azsli and RayTracingMaterialSrg.azsli
  23. // shader files that must match the setting of this define.
  24. #define USE_BINDLESS_SRG 1
  25. namespace AZ
  26. {
  27. namespace Render
  28. {
  29. static const uint32_t RayTracingGlobalSrgBindingSlot = 0;
  30. static const uint32_t RayTracingSceneSrgBindingSlot = 1;
  31. static const uint32_t RayTracingMaterialSrgBindingSlot = 2;
  32. static const uint32_t RayTracingTlasInstanceElementSize = 64;
  33. enum class RayTracingSubMeshBufferFlags : uint32_t
  34. {
  35. None = 0,
  36. Tangent = AZ_BIT(0),
  37. Bitangent = AZ_BIT(1),
  38. UV = AZ_BIT(2)
  39. };
  40. AZ_DEFINE_ENUM_BITWISE_OPERATORS(AZ::Render::RayTracingSubMeshBufferFlags);
  41. enum class RayTracingSubMeshTextureFlags : uint32_t
  42. {
  43. None = 0,
  44. BaseColor = AZ_BIT(0),
  45. Normal = AZ_BIT(1),
  46. Metallic = AZ_BIT(2),
  47. Roughness = AZ_BIT(3),
  48. Emissive = AZ_BIT(4)
  49. };
  50. AZ_DEFINE_ENUM_BITWISE_OPERATORS(AZ::Render::RayTracingSubMeshTextureFlags);
  51. //! This feature processor manages ray tracing data for a Scene
  52. class RayTracingFeatureProcessor
  53. : public RPI::FeatureProcessor
  54. {
  55. public:
  56. AZ_CLASS_ALLOCATOR(RayTracingFeatureProcessor, AZ::SystemAllocator)
  57. AZ_RTTI(AZ::Render::RayTracingFeatureProcessor, "{5017EFD3-A996-44B0-9ED2-C47609A2EE8D}", AZ::RPI::FeatureProcessor);
  58. static void Reflect(AZ::ReflectContext* context);
  59. RayTracingFeatureProcessor() = default;
  60. virtual ~RayTracingFeatureProcessor() = default;
  61. // FeatureProcessor overrides ...
  62. void Activate() override;
  63. void Deactivate() override;
  64. void OnRenderPipelineChanged(RPI::RenderPipeline* renderPipeline, RPI::SceneNotification::RenderPipelineChangeType changeType) override;
  65. struct Mesh;
  66. //! Contains data for a single subMesh
  67. struct SubMesh
  68. {
  69. // vertex streams
  70. RHI::Format m_positionFormat = RHI::Format::Unknown;
  71. RHI::StreamBufferView m_positionVertexBufferView;
  72. RHI::Ptr<RHI::BufferView> m_positionShaderBufferView;
  73. RHI::Format m_normalFormat = RHI::Format::Unknown;
  74. RHI::StreamBufferView m_normalVertexBufferView;
  75. RHI::Ptr<RHI::BufferView> m_normalShaderBufferView;
  76. RHI::Format m_tangentFormat = RHI::Format::Unknown;
  77. RHI::StreamBufferView m_tangentVertexBufferView;
  78. RHI::Ptr<RHI::BufferView> m_tangentShaderBufferView;
  79. RHI::Format m_bitangentFormat = RHI::Format::Unknown;
  80. RHI::StreamBufferView m_bitangentVertexBufferView;
  81. RHI::Ptr<RHI::BufferView> m_bitangentShaderBufferView;
  82. RHI::Format m_uvFormat = RHI::Format::Unknown;
  83. RHI::StreamBufferView m_uvVertexBufferView;
  84. RHI::Ptr<RHI::BufferView> m_uvShaderBufferView;
  85. // index buffer
  86. RHI::IndexBufferView m_indexBufferView;
  87. RHI::Ptr<RHI::BufferView> m_indexShaderBufferView;
  88. // vertex buffer usage flags
  89. RayTracingSubMeshBufferFlags m_bufferFlags = RayTracingSubMeshBufferFlags::None;
  90. // color of the bounced light from this sub-mesh
  91. AZ::Color m_irradianceColor = AZ::Color(1.0f);
  92. // ray tracing Blas
  93. RHI::Ptr<RHI::RayTracingBlas> m_blas;
  94. // material data
  95. AZ::Color m_baseColor = AZ::Color(0.0f);
  96. float m_metallicFactor = 0.0f;
  97. float m_roughnessFactor = 0.0f;
  98. AZ::Color m_emissiveColor = AZ::Color(0.0f);
  99. // material texture usage flags
  100. RayTracingSubMeshTextureFlags m_textureFlags = RayTracingSubMeshTextureFlags::None;
  101. // material textures
  102. RHI::Ptr<const RHI::ImageView> m_baseColorImageView;
  103. RHI::Ptr<const RHI::ImageView> m_normalImageView;
  104. RHI::Ptr<const RHI::ImageView> m_metallicImageView;
  105. RHI::Ptr<const RHI::ImageView> m_roughnessImageView;
  106. RHI::Ptr<const RHI::ImageView> m_emissiveImageView;
  107. // parent mesh
  108. Mesh* m_mesh = nullptr;
  109. private:
  110. friend RayTracingFeatureProcessor;
  111. // index of this mesh in the subMesh list, also applies to the MeshInfo and MaterialInfo entries
  112. uint32_t m_globalIndex = InvalidIndex;
  113. // index of this mesh in the parent Mesh's subMesh list
  114. uint32_t m_subMeshIndex = InvalidIndex;
  115. };
  116. using SubMeshVector = AZStd::vector<SubMesh>;
  117. using IndexVector = AZStd::vector<uint32_t>;
  118. //! Contains data for the top level mesh, including the list of sub-meshes
  119. struct Mesh
  120. {
  121. // assetId of the model
  122. AZ::Data::AssetId m_assetId = AZ::Data::AssetId{};
  123. // transform
  124. AZ::Transform m_transform = AZ::Transform::CreateIdentity();
  125. // non-uniform scale
  126. AZ::Vector3 m_nonUniformScale = AZ::Vector3::CreateOne();
  127. // reflection probe
  128. struct ReflectionProbe
  129. {
  130. AZ::Transform m_modelToWorld;
  131. AZ::Vector3 m_outerObbHalfLengths;
  132. AZ::Vector3 m_innerObbHalfLengths;
  133. bool m_useParallaxCorrection = false;
  134. float m_exposure = 0.0f;
  135. Data::Instance<RPI::Image> m_reflectionProbeCubeMap;
  136. };
  137. ReflectionProbe m_reflectionProbe;
  138. private:
  139. friend RayTracingFeatureProcessor;
  140. // indices of subMeshes in the subMesh list
  141. IndexVector m_subMeshIndices;
  142. };
  143. //! Adds ray tracing data for a mesh.
  144. //! This will cause an update to the RayTracing acceleration structure on the next frame
  145. void AddMesh(const AZ::Uuid& uuid, const Mesh& rayTracingMesh, const SubMeshVector& subMeshes);
  146. //! Removes ray tracing data for a mesh.
  147. //! This will cause an update to the RayTracing acceleration structure on the next frame
  148. void RemoveMesh(const AZ::Uuid& uuid);
  149. //! Sets the ray tracing mesh transform
  150. //! This will cause an update to the RayTracing acceleration structure on the next frame
  151. void SetMeshTransform(const AZ::Uuid& uuid, const AZ::Transform transform, const AZ::Vector3 nonUniformScale);
  152. //! Sets the reflection probe for a mesh
  153. void SetMeshReflectionProbe(const AZ::Uuid& uuid, const Mesh::ReflectionProbe& reflectionProbe);
  154. //! Retrieves the map of all subMeshes in the scene
  155. const SubMeshVector& GetSubMeshes() const { return m_subMeshes; }
  156. SubMeshVector& GetSubMeshes() { return m_subMeshes; }
  157. //! Retrieves the RayTracingSceneSrg
  158. Data::Instance<RPI::ShaderResourceGroup> GetRayTracingSceneSrg() const { return m_rayTracingSceneSrg; }
  159. //! Retrieves the RayTracingMaterialSrg
  160. Data::Instance<RPI::ShaderResourceGroup> GetRayTracingMaterialSrg() const { return m_rayTracingMaterialSrg; }
  161. //! Retrieves the RayTracingTlas
  162. const RHI::Ptr<RHI::RayTracingTlas>& GetTlas() const { return m_tlas; }
  163. RHI::Ptr<RHI::RayTracingTlas>& GetTlas() { return m_tlas; }
  164. //! Retrieves the revision number of the ray tracing data.
  165. //! This is used to determine if the RayTracingShaderTable needs to be rebuilt.
  166. uint32_t GetRevision() const { return m_revision; }
  167. //! Retrieves the buffer pools used for ray tracing operations.
  168. RHI::RayTracingBufferPools& GetBufferPools() { return *m_bufferPools; }
  169. //! Retrieves the total number of ray tracing meshes.
  170. uint32_t GetSubMeshCount() const { return m_subMeshCount; }
  171. //! Retrieves the attachmentId of the Tlas for this scene
  172. RHI::AttachmentId GetTlasAttachmentId() const { return m_tlasAttachmentId; }
  173. //! Retrieves the GPU buffer containing information for all ray tracing meshes.
  174. const Data::Instance<RPI::Buffer> GetMeshInfoGpuBuffer() const { return m_meshInfoGpuBuffer[m_currentMeshInfoFrameIndex]; }
  175. //! Retrieves the GPU buffer containing information for all ray tracing materials.
  176. const Data::Instance<RPI::Buffer> GetMaterialInfoGpuBuffer() const { return m_materialInfoGpuBuffer[m_currentMaterialInfoFrameIndex]; }
  177. //! Updates the RayTracingSceneSrg and RayTracingMaterialSrg, called after the TLAS is allocated in the RayTracingAccelerationStructurePass
  178. void UpdateRayTracingSrgs();
  179. struct SubMeshBlasInstance
  180. {
  181. RHI::Ptr<RHI::RayTracingBlas> m_blas;
  182. };
  183. struct MeshBlasInstance
  184. {
  185. uint32_t m_count = 0;
  186. AZStd::vector<SubMeshBlasInstance> m_subMeshes;
  187. // flag indicating if the Blas objects in the sub-mesh list are built
  188. bool m_blasBuilt = false;
  189. };
  190. using BlasInstanceMap = AZStd::unordered_map<AZ::Data::AssetId, MeshBlasInstance>;
  191. BlasInstanceMap& GetBlasInstances() { return m_blasInstanceMap; }
  192. private:
  193. AZ_DISABLE_COPY_MOVE(RayTracingFeatureProcessor);
  194. void UpdateMeshInfoBuffer();
  195. void UpdateMaterialInfoBuffer();
  196. void UpdateIndexLists();
  197. void UpdateRayTracingSceneSrg();
  198. void UpdateRayTracingMaterialSrg();
  199. // flag indicating if RayTracing is enabled, currently based on device support
  200. bool m_rayTracingEnabled = false;
  201. // mesh data for meshes that should be included in ray tracing operations,
  202. // this is a map of the mesh UUID to the ray tracing data for the sub-meshes
  203. using MeshMap = AZStd::map<AZ::Uuid, Mesh>;
  204. MeshMap m_meshes;
  205. SubMeshVector m_subMeshes;
  206. // buffer pools used in ray tracing operations
  207. RHI::Ptr<RHI::RayTracingBufferPools> m_bufferPools;
  208. // ray tracing acceleration structure (TLAS)
  209. RHI::Ptr<RHI::RayTracingTlas> m_tlas;
  210. // RayTracingScene and RayTracingMaterial asset and Srgs
  211. Data::Asset<RPI::ShaderAsset> m_rayTracingSrgAsset;
  212. Data::Instance<RPI::ShaderResourceGroup> m_rayTracingSceneSrg;
  213. Data::Instance<RPI::ShaderResourceGroup> m_rayTracingMaterialSrg;
  214. // current revision number of ray tracing data
  215. uint32_t m_revision = 0;
  216. // total number of ray tracing sub-meshes
  217. uint32_t m_subMeshCount = 0;
  218. // TLAS attachmentId
  219. RHI::AttachmentId m_tlasAttachmentId;
  220. // cached TransformServiceFeatureProcessor
  221. TransformServiceFeatureProcessor* m_transformServiceFeatureProcessor = nullptr;
  222. // mutex for the mesh and BLAS lists
  223. AZStd::mutex m_mutex;
  224. // structure for data in the m_meshInfoBuffer, shaders that use the buffer must match this type
  225. struct MeshInfo
  226. {
  227. // byte offsets into the mesh buffer views
  228. uint32_t m_indexByteOffset = 0;
  229. uint32_t m_positionByteOffset = 0;
  230. uint32_t m_normalByteOffset = 0;
  231. uint32_t m_tangentByteOffset = 0;
  232. uint32_t m_bitangentByteOffset = 0;
  233. uint32_t m_uvByteOffset = 0;
  234. RayTracingSubMeshBufferFlags m_bufferFlags = RayTracingSubMeshBufferFlags::None;
  235. uint32_t m_bufferStartIndex = 0;
  236. AZStd::array<float, 4> m_irradianceColor; // float4
  237. AZStd::array<float, 12> m_worldInvTranspose; // float3x4
  238. };
  239. // vector of MeshInfo, transferred to the meshInfoGpuBuffer
  240. using MeshInfoVector = AZStd::vector<MeshInfo>;
  241. MeshInfoVector m_meshInfos;
  242. static const uint32_t BufferFrameCount = 3;
  243. Data::Instance<RPI::Buffer> m_meshInfoGpuBuffer[BufferFrameCount];
  244. uint32_t m_currentMeshInfoFrameIndex = 0;
  245. // structure for data in the m_materialInfoBuffer, shaders that use the buffer must match this type
  246. struct alignas(16) MaterialInfo
  247. {
  248. AZStd::array<float, 4> m_baseColor; // float4
  249. AZStd::array<float, 3> m_emissiveColor; // float3
  250. float m_metallicFactor = 0.0f;
  251. float m_roughnessFactor = 0.0f;
  252. RayTracingSubMeshTextureFlags m_textureFlags = RayTracingSubMeshTextureFlags::None;
  253. uint32_t m_textureStartIndex = 0;
  254. uint32_t m_reflectionProbeCubeMapIndex = InvalidIndex;
  255. // reflection probe data, must match the structure in ReflectionProbeData.azlsi
  256. struct alignas(16) ReflectionProbeData
  257. {
  258. AZStd::array<float, 12> m_modelToWorld; // float3x4
  259. AZStd::array<float, 12> m_modelToWorldInverse; // float3x4
  260. AZStd::array<float, 3> m_outerObbHalfLengths; // float3
  261. float m_exposure = 0.0f;
  262. AZStd::array<float, 3> m_innerObbHalfLengths; // float3
  263. uint32_t m_useReflectionProbe = 0;
  264. uint32_t m_useParallaxCorrection = 0;
  265. AZStd::array<float, 3> m_padding;
  266. };
  267. ReflectionProbeData m_reflectionProbeData;
  268. };
  269. // vector of MaterialInfo, transferred to the materialInfoGpuBuffer
  270. using MaterialInfoVector = AZStd::vector<MaterialInfo>;
  271. MaterialInfoVector m_materialInfos;
  272. Data::Instance<RPI::Buffer> m_materialInfoGpuBuffer[BufferFrameCount];
  273. uint32_t m_currentMaterialInfoFrameIndex = 0;
  274. // update flags
  275. bool m_meshInfoBufferNeedsUpdate = false;
  276. bool m_materialInfoBufferNeedsUpdate = false;
  277. bool m_indexListNeedsUpdate = false;
  278. // side list for looking up existing BLAS objects so they can be re-used when the same mesh is added multiple times
  279. BlasInstanceMap m_blasInstanceMap;
  280. #if !USE_BINDLESS_SRG
  281. // Mesh buffer and material texture resources are managed with a RayTracingResourceList, which contains an internal
  282. // indirection list. This allows resource entries to be swapped inside the RayTracingResourceList when removing entries,
  283. // without invalidating the indices held here in the m_meshBufferIndices and m_materialTextureIndices lists.
  284. // mesh buffer and material texture resource lists, accessed by the shader through an unbounded array
  285. RayTracingResourceList<RHI::BufferView> m_meshBuffers;
  286. RayTracingResourceList<const RHI::ImageView> m_materialTextures;
  287. #endif
  288. // RayTracingIndexList implements an internal freelist chain stored inside the list itself, allowing entries to be
  289. // reused after elements are removed.
  290. // mesh buffer and material texture index lists, which contain the array indices of the mesh resources
  291. static const uint32_t NumMeshBuffersPerMesh = 6;
  292. RayTracingIndexList<NumMeshBuffersPerMesh> m_meshBufferIndices;
  293. static const uint32_t NumMaterialTexturesPerMesh = 5;
  294. RayTracingIndexList<NumMaterialTexturesPerMesh> m_materialTextureIndices;
  295. // Gpu buffers for the mesh and material index lists
  296. Data::Instance<RPI::Buffer> m_meshBufferIndicesGpuBuffer[BufferFrameCount];
  297. Data::Instance<RPI::Buffer> m_materialTextureIndicesGpuBuffer[BufferFrameCount];
  298. uint32_t m_currentIndexListFrameIndex = 0;
  299. };
  300. }
  301. }