@@ -141,6 +141,38 @@ class PBR_Renderer
141141 VERTEX_POS_PACK_MODE_64_BIT ,
142142 };
143143
144+ static constexpr Uint32 InvalidMorphTargetDataOffset = ~Uint32{0 };
145+
146+ // / One morph target selected for the active target palette.
147+ struct ActiveMorphTarget
148+ {
149+ Uint32 TargetIndex = 0 ;
150+ Float32 Weight = 0 ;
151+ };
152+
153+ // / Shader-readable data for one active morph target.
154+ // /
155+ // / Each referenced stream contains one tightly packed Float32 triplet per
156+ // / vertex. Delta offsets are measured in Float32 elements in the structured
157+ // / morph target buffer. InvalidMorphTargetDataOffset indicates that the
158+ // / target does not provide the corresponding attribute.
159+ struct MorphTargetShaderAttribs
160+ {
161+ Float32 Weight = 0 ;
162+ Uint32 PositionDeltaOffset = InvalidMorphTargetDataOffset;
163+ Uint32 NormalDeltaOffset = InvalidMorphTargetDataOffset;
164+ Uint32 TangentDeltaOffset = InvalidMorphTargetDataOffset;
165+ };
166+
167+ // / Selects up to MaxActiveTargetCount nonzero weights with the greatest
168+ // / absolute magnitude. The result is sorted by descending magnitude, with
169+ // / lower target indices ordered first when magnitudes are equal. Signed
170+ // / weights are preserved.
171+ static Uint32 SelectActiveMorphTargets (const Float32* pWeights,
172+ Uint32 WeightCount,
173+ ActiveMorphTarget* pActiveTargets,
174+ Uint32 MaxActiveTargetCount) noexcept ;
175+
144176 // / Renderer create info
145177 struct CreateInfo
146178 {
@@ -201,6 +233,11 @@ class PBR_Renderer
201233 // / Disable this when joint data is supplied through renderer-specific SRBs.
202234 bool CreateDefaultJointsBuffer = true ;
203235
236+ // / Whether to create a default morph target buffer when
237+ // / pMorphTargetBuffer is null. Disable this when morph target data is
238+ // / supplied through renderer-specific SRBs.
239+ bool CreateDefaultMorphTargetBuffer = true ;
240+
204241 // / Whether to enable shadows.
205242 // / A pipeline state can use shadows only if this flag is set to true.
206243 bool EnableShadows = false ;
@@ -304,6 +341,12 @@ class PBR_Renderer
304341 // / If set to 0, the animation will be disabled.
305342 Uint32 MaxJointCount = 64 ;
306343
344+ // / Maximum number of morph targets blended by a draw.
345+ // /
346+ // / The value determines the size of the per-primitive morph palette
347+ // / and bounds vertex shader work. Set to zero to disable morph targets.
348+ Uint32 MaxActiveMorphTargetCount = 4 ;
349+
307350 // / Joints buffer mode.
308351 JOINTS_BUFFER_MODE JointsBufferMode = JOINTS_BUFFER_MODE_UNIFORM ;
309352
@@ -324,6 +367,7 @@ class PBR_Renderer
324367 // / float4 Weight0 : ATTRIB5; // If PSO_FLAG_USE_JOINTS is set
325368 // / float4 Color : ATTRIB6; // If PSO_FLAG_USE_VERTEX_COLORS is set
326369 // / float3 Tangent : ATTRIB7; // If PSO_FLAG_USE_VERTEX_TANGENTS is set
370+ // / uint VertexID : SV_VertexID; // If PSO_FLAG_USE_MORPH_TARGETS is set
327371 // / };
328372 InputLayoutDesc InputLayout;
329373
@@ -372,6 +416,11 @@ class PBR_Renderer
372416 // / allocate the buffer.
373417 IBuffer* pJointsBuffer = nullptr ;
374418
419+ // / A pointer to the user-provided morph target buffer.
420+ // / If null and CreateDefaultMorphTargetBuffer is true, the renderer
421+ // / will allocate a minimal fallback buffer.
422+ IBuffer* pMorphTargetBuffer = nullptr ;
423+
375424 // / Texture attribute index info
376425 std::array<int , TEXTURE_ATTRIB_ID_COUNT > TextureAttribIndices{};
377426
@@ -482,6 +531,7 @@ class PBR_Renderer
482531 IBuffer* GetPBRPrimitiveAttribsCB () const { return m_PBRPrimitiveAttribsCB; }
483532 IBuffer* GetPBRMaterialAttribsCB () const { return m_PBRMaterialAttribsCB; }
484533 IBuffer* GetJointsBuffer () const { return m_JointsBuffer; }
534+ IBuffer* GetMorphTargetBuffer () const { return m_MorphTargetBuffer; }
485535 // clang-format on
486536
487537 static constexpr TEXTURE_FORMAT PrefilteredEnvMapFmt = TEX_FORMAT_RGBA16_FLOAT ;
@@ -655,8 +705,9 @@ class PBR_Renderer
655705 PSO_FLAG_UNSHADED = PSO_FLAG_BIT (39 ),
656706 PSO_FLAG_COMPUTE_MOTION_VECTORS = PSO_FLAG_BIT (40 ),
657707 PSO_FLAG_ENABLE_SHADOWS = PSO_FLAG_BIT (41 ),
708+ PSO_FLAG_USE_MORPH_TARGETS = PSO_FLAG_BIT (42 ),
658709
659- PSO_FLAG_LAST = PSO_FLAG_ENABLE_SHADOWS ,
710+ PSO_FLAG_LAST = PSO_FLAG_USE_MORPH_TARGETS ,
660711
661712 PSO_FLAG_FIRST_USER_DEFINED = PSO_FLAG_LAST << 1ull ,
662713
@@ -878,6 +929,12 @@ class PBR_Renderer
878929 // / Optional joints buffer. When null, the renderer-owned buffer is used.
879930 IBuffer* pJointsBuffer = nullptr ;
880931
932+ // / Optional structured Float32 buffer containing morph target deltas.
933+ // / When null, the renderer-owned buffer is used. A buffer containing
934+ // / the referenced data must be provided when PSO_FLAG_USE_MORPH_TARGETS
935+ // / is enabled.
936+ IBuffer* pMorphTargetDeltas = nullptr ;
937+
881938 // / Optional shadow map view.
882939 ITextureView* pShadowMap = nullptr ;
883940
@@ -952,10 +1009,11 @@ class PBR_Renderer
9521009 static void * WriteSkinningData (void * pDst, const WriteSkinningDataAttribs& Attribs, bool PackMatrixRowMajor, Uint32 MaxJointCount);
9531010 void * WriteSkinningData (void * pDst, const WriteSkinningDataAttribs& Attribs);
9541011
955- static Uint32 GetJointsDataSize (Uint32 MaxJointCount, bool UsePrevFrameTransforms);
956- Uint32 GetJointsDataSize (Uint32 JointCount, PSO_FLAGS PSOFlags) const ;
957- Uint32 GetJointsBufferSize () const ;
958- const char * GetJointTransformsVarName () const ;
1012+ static Uint32 GetJointsDataSize (Uint32 MaxJointCount, bool UsePrevFrameTransforms);
1013+ Uint32 GetJointsDataSize (Uint32 JointCount, PSO_FLAGS PSOFlags) const ;
1014+ Uint32 GetJointsBufferSize () const ;
1015+ const char * GetJointTransformsVarName () const ;
1016+ static const char * GetMorphTargetDeltasVarName ();
9591017
9601018 // / Packs normal into a single 32-bit uint.
9611019 // /
@@ -1113,6 +1171,7 @@ class PBR_Renderer
11131171 RefCntAutoPtr<IBuffer> m_PBRPrimitiveAttribsCB;
11141172 RefCntAutoPtr<IBuffer> m_PBRMaterialAttribsCB;
11151173 RefCntAutoPtr<IBuffer> m_JointsBuffer;
1174+ RefCntAutoPtr<IBuffer> m_MorphTargetBuffer;
11161175
11171176 std::unordered_set<std::string> m_GeneratedIncludes;
11181177
0 commit comments