SkinnedMeshDispatchItem.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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 <Atom/Feature/SkinnedMesh/SkinnedMeshInputBuffers.h>
  10. #include <Atom/Feature/SkinnedMesh/SkinnedMeshShaderOptions.h>
  11. #include <SkinnedMesh/SkinnedMeshShaderOptionsCache.h>
  12. #include <Atom/RHI/DispatchItem.h>
  13. #include <Atom/RPI.Reflect/Shader/ShaderOptionGroup.h>
  14. #include <AtomCore/Instance/Instance.h>
  15. namespace AZ
  16. {
  17. namespace RHI
  18. {
  19. class BufferView;
  20. class PipelineState;
  21. }
  22. namespace RPI
  23. {
  24. class Buffer;
  25. class ModelLod;
  26. class Shader;
  27. class ShaderResourceGroup;
  28. }
  29. namespace Render
  30. {
  31. class SkinnedMeshFeatureProcessor;
  32. //! Holds and manages an RHI DispatchItem for a specific skinned mesh, and the resources that are needed to build and maintain it.
  33. class SkinnedMeshDispatchItem
  34. : private SkinnedMeshShaderOptionNotificationBus::Handler
  35. {
  36. public:
  37. AZ_CLASS_ALLOCATOR(SkinnedMeshDispatchItem, AZ::SystemAllocator);
  38. SkinnedMeshDispatchItem() = delete;
  39. //! Create one dispatch item per mesh for each actor instance
  40. explicit SkinnedMeshDispatchItem(
  41. AZStd::intrusive_ptr<SkinnedMeshInputBuffers> inputBuffers,
  42. const SkinnedMeshOutputVertexOffsets& outputBufferOffsetsInBytes,
  43. uint32_t positionHistoryOutputBufferOffsetInBytes,
  44. uint32_t lodIndex,
  45. uint32_t meshIndex,
  46. Data::Instance<RPI::Buffer> skinningMatrices,
  47. const SkinnedMeshShaderOptions& shaderOptions,
  48. SkinnedMeshFeatureProcessor* skinnedMeshFeatureProcessor,
  49. MorphTargetInstanceMetaData morphTargetInstanceMetaData,
  50. float morphTargetDeltaIntegerEncoding
  51. );
  52. ~SkinnedMeshDispatchItem();
  53. // The event handler cannot be copied
  54. AZ_DISABLE_COPY_MOVE(SkinnedMeshDispatchItem);
  55. bool Init();
  56. const RHI::DispatchItem& GetRHIDispatchItem() const;
  57. Data::Instance<RPI::Buffer> GetBoneTransforms() const;
  58. uint32_t GetVertexCount() const;
  59. void Enable();
  60. void Disable();
  61. bool IsEnabled() const;
  62. private:
  63. // SkinnedMeshShaderOptionNotificationBus::Handler
  64. void OnShaderReinitialized(const CachedSkinnedMeshShaderOptions* cachedShaderOptions) override;
  65. RHI::DispatchItem m_dispatchItem;
  66. // The skinning shader used for this instance
  67. Data::Instance<RPI::Shader> m_skinningShader;
  68. // Offsets into the SkinnedMeshOutputVertexStream where the lod streams start for this mesh
  69. SkinnedMeshOutputVertexOffsets m_outputBufferOffsetsInBytes;
  70. // Offset into the SkinnedMeshOutputVertexStream where the position history stream starts for this mesh
  71. uint32_t m_positionHistoryBufferOffsetInBytes;
  72. // The unskinned vertices used as the source of the skinning
  73. AZStd::intrusive_ptr<SkinnedMeshInputBuffers> m_inputBuffers;
  74. // The index of the lod within m_inputBuffers that is represented by the DispatchItem
  75. uint32_t m_lodIndex;
  76. // The index of the mesh within the lod that is represented by the DispatchItem
  77. uint32_t m_meshIndex;
  78. // The per-object shader resource group
  79. Data::Instance<RPI::ShaderResourceGroup> m_instanceSrg;
  80. // Buffer with the bone transforms
  81. Data::Instance<RPI::Buffer> m_boneTransforms;
  82. // Options for the skinning shader
  83. SkinnedMeshShaderOptions m_shaderOptions;
  84. RPI::ShaderOptionGroup m_shaderOptionGroup;
  85. // MetaData for the morph target that is specific to this instance
  86. MorphTargetInstanceMetaData m_morphTargetInstanceMetaData;
  87. // A conservative value for encoding/decoding the accumulated deltas
  88. float m_morphTargetDeltaIntegerEncoding;
  89. // Skip the skinning dispatch if this is false
  90. bool m_isEnabled = true;
  91. };
  92. //! The skinned mesh compute shader has Nx1x1 threads per group and dispatches a total number of threads greater than or equal to the number of vertices in the mesh, with one vertex skinned per thread.
  93. //! We increase the total number of threads along the x dimension until it overflows what can fit in that dimension,
  94. //! and subsequently increment the total number of threads in the y dimension as much as needed for the total number of threads to equal or exceed the vertex count.
  95. void CalculateSkinnedMeshTotalThreadsPerDimension(uint32_t vertexCount, uint32_t& xThreads, uint32_t& yThreads);
  96. } // namespace Render
  97. } // namespace AZ