13 IEffectSkinning
Chuck Walbourn редактировал(а) эту страницу 2022-04-26 16:56:25 -07:00
DirectXTK Effects

This abstract interface controls skinning animation matrices.

Effects that implement this interface typically require BLENDINDICES and BLENDWEIGHT semantic data in the vertex input layout.

Related tutorial: Using skinned models

Obtaining the interface

There are two methods used in DirectX Tool Kit. For simple cases, just maintain a reference directly to the desired effect class:

std::shared_ptr<SkinnedEffect> effect(device, EffectFlags::None, pd);

...

effect->SetBoneTransforms( bones.get(), boneCount );

For more general cases where a number of effect classes can be in use (such as Model which uses a mix of BasicEffect, DualTextureEffect, and/or SkinnedEffect), use Run-Time Type Information (RTTI) to obtain the interface.

std::shared_ptr<SkinnedEffect> effect(device, EffectFlags::None, pd);

...

auto iskin = dynamic_cast<IEffectSkinning*>( effect.get() );
if ( iskin )
{
    iskin->SetBoneTransforms( bones.get(), boneCount );
}

Skinning

The skinning interface is primarily used to set the per-bone transformation matrices for rendering. This is accomplished through the SetBoneTransforms method. Because the method takes a pointer to XMMATRIX, the memory buffer must be 16-byte aligned. While this is the default of new and malloc on 64-bit platforms, this is not true by default for 32-bit platforms. Use of _aligned_malloc is recommended.

struct aligned_deleter { void operator()(void* p) { _aligned_free(p); } };

std::unique_ptr<XMMATRIX[], aligned_deleter> bones(
        reinterpret_cast<XMMATRIX*>( _aligned_malloc(
            sizeof(XMMATRIX) * boneCount, 16 ) ) );

...

// Simple time-based uniform scaling
float s = 1 + sin(time * 1.7f) * 0.5f;
XMMATRIX scale = XMMatrixScaling(s,s,s);

for (size_t j=0; j < boneCount; ++j )
{
    bones[ j ] = scale;
}

effect->SetBoneTransforms(bones.get(), boneCount);

Note that the maximum bone count must be <= MaxBones (72).

You can call ResetBoneTransforms to reset all per-bone transforms to the identity, which is also the default when the effect is newly created.

Built-in Effect Notes

SkinnedEffect

See Built-in effects, permutations, and performance for performance costs of the various shader permutations.

SkinnedNormalMapEffect, SkinnedPBREffect

These built-in effects also support skinning.

Remark

As an optimization, the skinning effects assume that all the matrices are affine transformations, and that the final column is (0 0 0 1). This means that the value of the last column is effectively ignored when set into the constant buffer containing the bone transformations (i.e. the shaders use float4x3)