3
0

RayTracingFeatureProcessor.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  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/IndexBufferView.h>
  13. #include <Atom/RHI/StreamBufferView.h>
  14. #include <Atom/RHI/RayTracingAccelerationStructure.h>
  15. #include <Atom/RHI/RayTracingBufferPools.h>
  16. #include <Atom/RHI/DeviceBufferView.h>
  17. #include <Atom/RHI/DeviceImageView.h>
  18. #include <Atom/RPI.Public/Buffer/RingBuffer.h>
  19. #include <Atom/RPI.Public/Shader/Shader.h>
  20. #include <Atom/Utils/StableDynamicArray.h>
  21. #include <AzCore/Math/Aabb.h>
  22. #include <AzCore/Math/Color.h>
  23. #include <AzCore/Math/Transform.h>
  24. // this define specifies that the mesh buffers and material textures are stored in the Bindless Srg
  25. // Note1: The previous implementation using separate unbounded arrays is preserved since it demonstrates a TDR caused by
  26. // the RHI unbounded array allocation. This define and the previous codepath can be removed once the TDR is
  27. // investigated and resolved.
  28. // Note2: There are corresponding USE_BINDLESS_SRG defines in the RayTracingSceneSrg.azsli and RayTracingMaterialSrg.azsli
  29. // shader files that must match the setting of this define.
  30. #define USE_BINDLESS_SRG 1
  31. namespace AZ
  32. {
  33. namespace Render
  34. {
  35. static const uint32_t RayTracingGlobalSrgBindingSlot = 0;
  36. static const uint32_t RayTracingSceneSrgBindingSlot = 1;
  37. static const uint32_t RayTracingMaterialSrgBindingSlot = 2;
  38. static const uint32_t RayTracingTlasInstanceElementSize = 64;
  39. enum class RayTracingSubMeshBufferFlags : uint32_t
  40. {
  41. None = 0,
  42. Tangent = AZ_BIT(0),
  43. Bitangent = AZ_BIT(1),
  44. UV = AZ_BIT(2)
  45. };
  46. AZ_DEFINE_ENUM_BITWISE_OPERATORS(AZ::Render::RayTracingSubMeshBufferFlags);
  47. enum class RayTracingSubMeshTextureFlags : uint32_t
  48. {
  49. None = 0,
  50. BaseColor = AZ_BIT(0),
  51. Normal = AZ_BIT(1),
  52. Metallic = AZ_BIT(2),
  53. Roughness = AZ_BIT(3),
  54. Emissive = AZ_BIT(4)
  55. };
  56. AZ_DEFINE_ENUM_BITWISE_OPERATORS(AZ::Render::RayTracingSubMeshTextureFlags);
  57. //! This feature processor manages ray tracing data for a Scene
  58. class RayTracingFeatureProcessor
  59. : public RPI::FeatureProcessor
  60. {
  61. public:
  62. AZ_CLASS_ALLOCATOR(RayTracingFeatureProcessor, AZ::SystemAllocator)
  63. AZ_RTTI(AZ::Render::RayTracingFeatureProcessor, "{5017EFD3-A996-44B0-9ED2-C47609A2EE8D}", AZ::RPI::FeatureProcessor);
  64. static void Reflect(AZ::ReflectContext* context);
  65. RayTracingFeatureProcessor() = default;
  66. virtual ~RayTracingFeatureProcessor() = default;
  67. // FeatureProcessor overrides ...
  68. void Activate() override;
  69. void Deactivate() override;
  70. void OnRenderPipelineChanged(RPI::RenderPipeline* renderPipeline, RPI::SceneNotification::RenderPipelineChangeType changeType) override;
  71. struct Mesh;
  72. //! Contains material data for a single subMesh
  73. struct SubMeshMaterial
  74. {
  75. // color of the bounced light from this sub-mesh
  76. AZ::Color m_irradianceColor = AZ::Color(1.0f);
  77. // material data
  78. AZ::Color m_baseColor = AZ::Color(0.0f);
  79. float m_metallicFactor = 0.0f;
  80. float m_roughnessFactor = 0.0f;
  81. AZ::Color m_emissiveColor = AZ::Color(0.0f);
  82. // material texture usage flags
  83. RayTracingSubMeshTextureFlags m_textureFlags = RayTracingSubMeshTextureFlags::None;
  84. // material textures
  85. RHI::Ptr<const RHI::ImageView> m_baseColorImageView;
  86. RHI::Ptr<const RHI::ImageView> m_normalImageView;
  87. RHI::Ptr<const RHI::ImageView> m_metallicImageView;
  88. RHI::Ptr<const RHI::ImageView> m_roughnessImageView;
  89. RHI::Ptr<const RHI::ImageView> m_emissiveImageView;
  90. };
  91. //! Contains data for a single subMesh
  92. struct SubMesh
  93. {
  94. // vertex streams
  95. RHI::Format m_positionFormat = RHI::Format::Unknown;
  96. RHI::StreamBufferView m_positionVertexBufferView;
  97. RHI::Ptr<RHI::BufferView> m_positionShaderBufferView;
  98. RHI::Format m_normalFormat = RHI::Format::Unknown;
  99. RHI::StreamBufferView m_normalVertexBufferView;
  100. RHI::Ptr<RHI::BufferView> m_normalShaderBufferView;
  101. RHI::Format m_tangentFormat = RHI::Format::Unknown;
  102. RHI::StreamBufferView m_tangentVertexBufferView;
  103. RHI::Ptr<RHI::BufferView> m_tangentShaderBufferView;
  104. RHI::Format m_bitangentFormat = RHI::Format::Unknown;
  105. RHI::StreamBufferView m_bitangentVertexBufferView;
  106. RHI::Ptr<RHI::BufferView> m_bitangentShaderBufferView;
  107. RHI::Format m_uvFormat = RHI::Format::Unknown;
  108. RHI::StreamBufferView m_uvVertexBufferView;
  109. RHI::Ptr<RHI::BufferView> m_uvShaderBufferView;
  110. // index buffer
  111. RHI::IndexBufferView m_indexBufferView;
  112. RHI::Ptr<RHI::BufferView> m_indexShaderBufferView;
  113. // vertex buffer usage flags
  114. RayTracingSubMeshBufferFlags m_bufferFlags = RayTracingSubMeshBufferFlags::None;
  115. // ray tracing Blas
  116. RHI::Ptr<RHI::RayTracingBlas> m_blas;
  117. // submesh material
  118. SubMeshMaterial m_material;
  119. // parent mesh
  120. Mesh* m_mesh = nullptr;
  121. private:
  122. friend RayTracingFeatureProcessor;
  123. // index of this mesh in the subMesh list, also applies to the MeshInfo and MaterialInfo entries
  124. uint32_t m_globalIndex = InvalidIndex;
  125. // index of this mesh in the parent Mesh's subMesh list
  126. uint32_t m_subMeshIndex = InvalidIndex;
  127. };
  128. using SubMeshVector = AZStd::vector<SubMesh>;
  129. using SubMeshMaterialVector = AZStd::vector<SubMeshMaterial>;
  130. using IndexVector = AZStd::vector<uint32_t>;
  131. //! Contains data for the top level mesh, including the list of sub-meshes
  132. struct Mesh
  133. {
  134. // assetId of the model
  135. AZ::Data::AssetId m_assetId = AZ::Data::AssetId{};
  136. // transform
  137. AZ::Transform m_transform = AZ::Transform::CreateIdentity();
  138. // non-uniform scale
  139. AZ::Vector3 m_nonUniformScale = AZ::Vector3::CreateOne();
  140. // instance mask. Used to include/exclude mesh instances from TraceRay() calls
  141. uint32_t m_instanceMask = 0;
  142. bool m_isSkinnedMesh = false;
  143. // reflection probe
  144. struct ReflectionProbe
  145. {
  146. AZ::Transform m_modelToWorld;
  147. AZ::Vector3 m_outerObbHalfLengths;
  148. AZ::Vector3 m_innerObbHalfLengths;
  149. bool m_useParallaxCorrection = false;
  150. float m_exposure = 0.0f;
  151. Data::Instance<RPI::Image> m_reflectionProbeCubeMap;
  152. };
  153. ReflectionProbe m_reflectionProbe;
  154. private:
  155. friend RayTracingFeatureProcessor;
  156. // indices of subMeshes in the subMesh list
  157. IndexVector m_subMeshIndices;
  158. };
  159. //! Contains data for procedural geometry which uses an intersection shader for hit detection
  160. struct ProceduralGeometryType
  161. {
  162. Name m_name;
  163. Data::Instance<RPI::Shader> m_intersectionShader;
  164. Name m_intersectionShaderName;
  165. uint32_t m_bindlessBufferIndex;
  166. int m_instanceCount = 0;
  167. };
  168. using ProceduralGeometryTypeHandle = StableDynamicArrayHandle<ProceduralGeometryType>;
  169. using ProceduralGeometryTypeWeakHandle = StableDynamicArrayWeakHandle<ProceduralGeometryType>;
  170. //! Contains data for procedural geometry instances
  171. struct ProceduralGeometry
  172. {
  173. Uuid m_uuid;
  174. ProceduralGeometryTypeWeakHandle m_typeHandle;
  175. Aabb m_aabb;
  176. uint32_t m_instanceMask;
  177. Transform m_transform = Transform::CreateIdentity();
  178. AZ::Vector3 m_nonUniformScale = Vector3::CreateOne();
  179. RHI::Ptr<RHI::RayTracingBlas> m_blas;
  180. uint32_t m_localInstanceIndex;
  181. };
  182. using ProceduralGeometryTypeList = StableDynamicArray<ProceduralGeometryType>;
  183. using ProceduralGeometryList = AZStd::vector<ProceduralGeometry>;
  184. //! Registers a new procedural geometry type, which uses an intersection shader to determine hits for ray tracing.
  185. //! \param name The name this procedural geometry type should be associated with. It must be unique within the ray tracing
  186. //! pipeline as it is used to match hit group records to hit groups.
  187. //! \param intersectionShader The intersection that should be used for procedural geometry of this type. The intersection shader
  188. //! *must* include the file \<Atom/Features/RayTracing/RayTracingSrgs.azsli\> and must use the struct
  189. //! `ProceduralGeometryIntersectionAttributes` to forward its hit parameters to ReportHit().
  190. //! \param intersectionShaderName The name of the intersection shader entry function within m_intersectionShader.
  191. //! \param bindlessBufferIndex A single 32-bit value which can be queried in the intersection shader with
  192. //! `GetBindlessBufferIndex()`. This value is in most cases obtained by calling GetBindlessReadIndex() on a RHI BufferView, such
  193. //! that it can be accessed with `Bindless::GetByteAddressBuffer(GetBindlessBufferIndex())` in the intersection shader.
  194. //! \return A handle to the created type. If this handle is destroyed (by falling out of scope or calling `.Free()`), this
  195. //! procedural geometry type is also destroyed. This handle should be regarded as an opaque pointer, meaning that no member
  196. //! variables should be accessed or changed directly.
  197. ProceduralGeometryTypeHandle RegisterProceduralGeometryType(
  198. const AZStd::string& name,
  199. const Data::Instance<RPI::Shader>& intersectionShader,
  200. const AZStd::string& intersectionShaderName,
  201. uint32_t bindlessBufferIndex = static_cast<uint32_t>(-1));
  202. //! Sets the bindlessBufferIndex of a procedural geometry type. This is necessary if the buffer, whose bindless read index was
  203. //! passed to `RegisterProceduralGeometryType`, is resized or recreated.
  204. //! \param geometryTypeHandle A weak handle of a procedural geometry type (obtained by calling `.GetWeakHandle()` on the handle
  205. //! returned by `RegisterProceduralGeometryType`.
  206. //! \param bindlessBufferIndex A single 32-bit value which can be queried in the intersection shader with
  207. //! `GetBindlessBufferIndex()`.
  208. void SetProceduralGeometryTypeBindlessBufferIndex(
  209. ProceduralGeometryTypeWeakHandle geometryTypeHandle, uint32_t bindlessBufferIndex);
  210. //! Adds a procedural geometry to the ray tracing scene.
  211. //! \param geometryTypeHandle A weak handle of a procedural geometry type (obtained by calling `.GetWeakHandle()` on the handle
  212. //! returned by `RegisterProceduralGeometryType`.
  213. //! \param uuid The Uuid this geometry instance should be associated with.
  214. //! \param aabb The axis-aligned bounding box of this geometry instance.
  215. //! \param material The material of this geometry instance.
  216. //! \param instanceMask Used to include/exclude mesh instances from TraceRay() calls.
  217. //! \param localInstanceIndex An index which can be queried in the intersection shader with `GetLocalInstanceIndex()` and can be
  218. //! used together with `GetBindlessBufferIndex()` to access per-instance geometry data.
  219. void AddProceduralGeometry(
  220. ProceduralGeometryTypeWeakHandle geometryTypeHandle,
  221. const Uuid& uuid,
  222. const Aabb& aabb,
  223. const SubMeshMaterial& material,
  224. RHI::RayTracingAccelerationStructureInstanceInclusionMask instanceMask,
  225. uint32_t localInstanceIndex);
  226. //! Sets the transform of a procedural geometry instance.
  227. //! \param uuid The Uuid of the procedural geometry which must have been added with `AddProceduralGeometry` before.
  228. //! \param transform The transform of the procedural geometry instance.
  229. //! \param nonUniformScale The non-uniform scale of the procedural geometry instance.
  230. void SetProceduralGeometryTransform(
  231. const Uuid& uuid, const Transform& transform, const Vector3& nonUniformScale = Vector3::CreateOne());
  232. //! Sets the local index by which this instance can be addressed in the intersection shader.
  233. //! \param uuid The Uuid of the procedural geometry which must have been added with `AddProceduralGeometry` before.
  234. //! \param localInstanceIndex An index which can be queried in the intersection shader with `GetLocalInstanceIndex()` and can be
  235. //! used together with `GetBindlessBufferIndex()` to access per-instance geometry data.
  236. void SetProceduralGeometryLocalInstanceIndex(const Uuid& uuid, uint32_t localInstanceIndex);
  237. //! Sets the material of a procedural geometry instance.
  238. //! \param uuid The Uuid of the procedural geometry which must have been added with `AddProceduralGeometry` before.
  239. //! \param material The material of the procedural geometry instance.
  240. void SetProceduralGeometryMaterial(const Uuid& uuid, const SubMeshMaterial& material);
  241. //! Removes a procedural geometry instance from the ray tracing scene.
  242. //! \param uuid The Uuid of the procedrual geometry which must have been added with `AddProceduralGeometry` before.
  243. void RemoveProceduralGeometry(const Uuid& uuid);
  244. //! Returns the number of procedural geometry instances of a given procedural geometry type.
  245. //! \param geometryTypeHandle A weak handle of a procedural geometry type(obtained by calling `.GetWeakHandle()` on the handle
  246. //! returned by `RegisterProceduralGeometryType`.
  247. //! \return The number of procedural geometry instances of this type.
  248. int GetProceduralGeometryCount(ProceduralGeometryTypeWeakHandle geometryTypeHandle) const;
  249. //! Adds ray tracing data for a mesh.
  250. //! This will cause an update to the RayTracing acceleration structure on the next frame
  251. void AddMesh(const AZ::Uuid& uuid, const Mesh& rayTracingMesh, const SubMeshVector& subMeshes);
  252. //! Removes ray tracing data for a mesh.
  253. //! This will cause an update to the RayTracing acceleration structure on the next frame
  254. void RemoveMesh(const AZ::Uuid& uuid);
  255. //! Sets the ray tracing mesh transform
  256. //! This will cause an update to the RayTracing acceleration structure on the next frame
  257. void SetMeshTransform(const AZ::Uuid& uuid, const AZ::Transform transform, const AZ::Vector3 nonUniformScale);
  258. //! Sets the reflection probe for a mesh
  259. void SetMeshReflectionProbe(const AZ::Uuid& uuid, const Mesh::ReflectionProbe& reflectionProbe);
  260. //! Sets the material for a mesh
  261. void SetMeshMaterials(const AZ::Uuid& uuid, const SubMeshMaterialVector& subMeshMaterials);
  262. //! Retrieves the map of all subMeshes in the scene
  263. const SubMeshVector& GetSubMeshes() const { return m_subMeshes; }
  264. SubMeshVector& GetSubMeshes() { return m_subMeshes; }
  265. //! Retrieves the RayTracingSceneSrg
  266. Data::Instance<RPI::ShaderResourceGroup> GetRayTracingSceneSrg() const { return m_rayTracingSceneSrg; }
  267. //! Retrieves the RayTracingMaterialSrg
  268. Data::Instance<RPI::ShaderResourceGroup> GetRayTracingMaterialSrg() const { return m_rayTracingMaterialSrg; }
  269. //! Retrieves the RayTracingTlas
  270. const RHI::Ptr<RHI::RayTracingTlas>& GetTlas() const { return m_tlas; }
  271. RHI::Ptr<RHI::RayTracingTlas>& GetTlas() { return m_tlas; }
  272. //! Retrieves the revision number of the ray tracing data.
  273. //! This is used to determine if the RayTracingShaderTable needs to be rebuilt.
  274. uint32_t GetRevision() const { return m_revision; }
  275. //! Retrieves the revision number of the procedural geometry data of the ray tracing data.
  276. //! This is used to determine if the RayTracingPipelineState needs to be recreated.
  277. uint32_t GetProceduralGeometryTypeRevision() const { return m_proceduralGeometryTypeRevision; }
  278. uint32_t GetSkinnedMeshCount() const
  279. {
  280. return m_skinnedMeshCount;
  281. }
  282. //! Retrieves the buffer pools used for ray tracing operations.
  283. RHI::RayTracingBufferPools& GetBufferPools() { return *m_bufferPools; }
  284. //! Retrieves the total number of ray tracing meshes.
  285. uint32_t GetSubMeshCount() const { return m_subMeshCount; }
  286. //! Returns true if the ray tracing scene contains mesh geometry
  287. bool HasMeshGeometry() const { return m_subMeshCount != 0; }
  288. //! Returns true if the ray tracing scene contains procedural geometry
  289. bool HasProceduralGeometry() const { return !m_proceduralGeometry.empty(); }
  290. //! Returns true if the ray tracing scene contains mesh or procedural geometry
  291. bool HasGeometry() const { return HasMeshGeometry() || HasProceduralGeometry(); }
  292. //! Retrieves the attachmentId of the Tlas for this scene
  293. RHI::AttachmentId GetTlasAttachmentId() const { return m_tlasAttachmentId; }
  294. //! Retrieves the GPU buffer containing information for all ray tracing meshes.
  295. const Data::Instance<RPI::Buffer> GetMeshInfoGpuBuffer() const { return m_meshInfoGpuBuffer.GetCurrentBuffer(); }
  296. //! Retrieves the GPU buffer containing information for all ray tracing materials.
  297. const Data::Instance<RPI::Buffer> GetMaterialInfoGpuBuffer() const { return m_materialInfoGpuBuffer.GetCurrentBuffer(); }
  298. //! Updates the RayTracingSceneSrg and RayTracingMaterialSrg, called after the TLAS is allocated in the RayTracingAccelerationStructurePass
  299. void UpdateRayTracingSrgs();
  300. struct SubMeshBlasInstance
  301. {
  302. RHI::Ptr<RHI::RayTracingBlas> m_blas;
  303. };
  304. struct MeshBlasInstance
  305. {
  306. uint32_t m_count = 0;
  307. AZStd::vector<SubMeshBlasInstance> m_subMeshes;
  308. // flag indicating if the Blas objects in the sub-mesh list are built
  309. bool m_blasBuilt = false;
  310. bool m_isSkinnedMesh = false;
  311. };
  312. using BlasInstanceMap = AZStd::unordered_map<AZ::Data::AssetId, MeshBlasInstance>;
  313. BlasInstanceMap& GetBlasInstances() { return m_blasInstanceMap; }
  314. const ProceduralGeometryTypeList& GetProceduralGeometryTypes() const { return m_proceduralGeometryTypes; }
  315. const ProceduralGeometryList& GetProceduralGeometries() const { return m_proceduralGeometry; }
  316. private:
  317. AZ_DISABLE_COPY_MOVE(RayTracingFeatureProcessor);
  318. void UpdateMeshInfoBuffer();
  319. void UpdateProceduralGeometryInfoBuffer();
  320. void UpdateMaterialInfoBuffer();
  321. void UpdateIndexLists();
  322. void UpdateRayTracingSceneSrg();
  323. void UpdateRayTracingMaterialSrg();
  324. static RHI::RayTracingAccelerationStructureBuildFlags CreateRayTracingAccelerationStructureBuildFlags(bool isSkinnedMesh);
  325. // flag indicating if RayTracing is enabled, currently based on device support
  326. bool m_rayTracingEnabled = false;
  327. // mesh data for meshes that should be included in ray tracing operations,
  328. // this is a map of the mesh UUID to the ray tracing data for the sub-meshes
  329. using MeshMap = AZStd::map<AZ::Uuid, Mesh>;
  330. MeshMap m_meshes;
  331. SubMeshVector m_subMeshes;
  332. // buffer pools used in ray tracing operations
  333. RHI::Ptr<RHI::RayTracingBufferPools> m_bufferPools;
  334. // ray tracing acceleration structure (TLAS)
  335. RHI::Ptr<RHI::RayTracingTlas> m_tlas;
  336. // RayTracingScene and RayTracingMaterial asset and Srgs
  337. Data::Asset<RPI::ShaderAsset> m_rayTracingSrgAsset;
  338. Data::Instance<RPI::ShaderResourceGroup> m_rayTracingSceneSrg;
  339. Data::Instance<RPI::ShaderResourceGroup> m_rayTracingMaterialSrg;
  340. // current revision number of ray tracing data
  341. uint32_t m_revision = 0;
  342. uint32_t m_proceduralGeometryTypeRevision = 0;
  343. // total number of ray tracing sub-meshes
  344. uint32_t m_subMeshCount = 0;
  345. // TLAS attachmentId
  346. RHI::AttachmentId m_tlasAttachmentId;
  347. // cached TransformServiceFeatureProcessor
  348. TransformServiceFeatureProcessor* m_transformServiceFeatureProcessor = nullptr;
  349. // mutex for the mesh and BLAS lists
  350. AZStd::mutex m_mutex;
  351. // structure for data in the m_meshInfoBuffer, shaders that use the buffer must match this type
  352. struct MeshInfo
  353. {
  354. // byte offsets into the mesh buffer views
  355. uint32_t m_indexByteOffset = 0;
  356. uint32_t m_positionByteOffset = 0;
  357. uint32_t m_normalByteOffset = 0;
  358. uint32_t m_tangentByteOffset = 0;
  359. uint32_t m_bitangentByteOffset = 0;
  360. uint32_t m_uvByteOffset = 0;
  361. RayTracingSubMeshBufferFlags m_bufferFlags = RayTracingSubMeshBufferFlags::None;
  362. uint32_t m_bufferStartIndex = 0;
  363. AZStd::array<float, 12> m_worldInvTranspose; // float3x4
  364. };
  365. // vector of MeshInfo, transferred to the meshInfoGpuBuffer
  366. using MeshInfoVector = AZStd::vector<MeshInfo>;
  367. MeshInfoVector m_meshInfos;
  368. RPI::RingBuffer m_meshInfoGpuBuffer{ "RayTracingMeshInfo", RPI::CommonBufferPoolType::ReadOnly, sizeof(MeshInfo) };
  369. RPI::RingBuffer m_proceduralGeometryInfoGpuBuffer{ "ProceduralGeometryInfo", RPI::CommonBufferPoolType::ReadOnly, RHI::Format::R32G32_UINT };
  370. // structure for data in the m_materialInfoBuffer, shaders that use the buffer must match this type
  371. struct alignas(16) MaterialInfo
  372. {
  373. AZStd::array<float, 4> m_baseColor; // float4
  374. AZStd::array<float, 4> m_irradianceColor; // float4
  375. AZStd::array<float, 3> m_emissiveColor; // float3
  376. float m_metallicFactor = 0.0f;
  377. float m_roughnessFactor = 0.0f;
  378. RayTracingSubMeshTextureFlags m_textureFlags = RayTracingSubMeshTextureFlags::None;
  379. uint32_t m_textureStartIndex = InvalidIndex;
  380. uint32_t m_reflectionProbeCubeMapIndex = InvalidIndex;
  381. // reflection probe data, must match the structure in ReflectionProbeData.azlsi
  382. struct alignas(16) ReflectionProbeData
  383. {
  384. AZStd::array<float, 12> m_modelToWorld; // float3x4
  385. AZStd::array<float, 12> m_modelToWorldInverse; // float3x4
  386. AZStd::array<float, 3> m_outerObbHalfLengths; // float3
  387. float m_exposure = 0.0f;
  388. AZStd::array<float, 3> m_innerObbHalfLengths; // float3
  389. uint32_t m_useReflectionProbe = 0;
  390. uint32_t m_useParallaxCorrection = 0;
  391. AZStd::array<float, 3> m_padding;
  392. };
  393. ReflectionProbeData m_reflectionProbeData;
  394. };
  395. // vector of MaterialInfo, transferred to the materialInfoGpuBuffer
  396. using MaterialInfoVector = AZStd::vector<MaterialInfo>;
  397. AZStd::unordered_map<int, MaterialInfoVector> m_materialInfos;
  398. AZStd::unordered_map<int, MaterialInfoVector> m_proceduralGeometryMaterialInfos;
  399. RPI::RingBuffer m_materialInfoGpuBuffer{ "RayTracingMaterialInfo", RPI::CommonBufferPoolType::ReadOnly, sizeof(MaterialInfo) };
  400. // update flags
  401. bool m_meshInfoBufferNeedsUpdate = false;
  402. bool m_proceduralGeometryInfoBufferNeedsUpdate = false;
  403. bool m_materialInfoBufferNeedsUpdate = false;
  404. bool m_indexListNeedsUpdate = false;
  405. // side list for looking up existing BLAS objects so they can be re-used when the same mesh is added multiple times
  406. BlasInstanceMap m_blasInstanceMap;
  407. #if !USE_BINDLESS_SRG
  408. // Mesh buffer and material texture resources are managed with a RayTracingResourceList, which contains an internal
  409. // indirection list. This allows resource entries to be swapped inside the RayTracingResourceList when removing entries,
  410. // without invalidating the indices held here in the m_meshBufferIndices and m_materialTextureIndices lists.
  411. // mesh buffer and material texture resource lists, accessed by the shader through an unbounded array
  412. RayTracingResourceList<RHI::BufferView> m_meshBuffers;
  413. RayTracingResourceList<const RHI::ImageView> m_materialTextures;
  414. #endif
  415. // RayTracingIndexList implements an internal freelist chain stored inside the list itself, allowing entries to be
  416. // reused after elements are removed.
  417. // mesh buffer and material texture index lists, which contain the array indices of the mesh resources
  418. static const uint32_t NumMeshBuffersPerMesh = 6;
  419. AZStd::unordered_map<int, RayTracingIndexList<NumMeshBuffersPerMesh>> m_meshBufferIndices;
  420. static const uint32_t NumMaterialTexturesPerMesh = 5;
  421. AZStd::unordered_map<int, RayTracingIndexList<NumMaterialTexturesPerMesh>> m_materialTextureIndices;
  422. // Gpu buffers for the mesh and material index lists
  423. RPI::RingBuffer m_meshBufferIndicesGpuBuffer{ "RayTracingMeshBufferIndices", RPI::CommonBufferPoolType::ReadOnly, RHI::Format::R32_UINT };
  424. RPI::RingBuffer m_materialTextureIndicesGpuBuffer{ "RayTracingMaterialTextureIndices", RPI::CommonBufferPoolType::ReadOnly, RHI::Format::R32_UINT };
  425. uint32_t m_skinnedMeshCount = 0;
  426. ProceduralGeometryTypeList m_proceduralGeometryTypes;
  427. ProceduralGeometryList m_proceduralGeometry;
  428. AZStd::unordered_map<Uuid, size_t> m_proceduralGeometryLookup;
  429. void ConvertMaterial(MaterialInfo& materialInfo, const SubMeshMaterial& subMeshMaterial, int deviceIndex);
  430. };
  431. }
  432. }