https://qiita.com/YKVKDX12/items/cae702c31655f2bd8cce
の続編です
出力されるであろうアニメーション

ボーンに紐づいたポリゴンが回転するアニメーションです
画像ではわかりませんが、しばらく回転して、ウェイトの問題があるのか見えなくなります
この記事の構成
スキニングのコアはボーンとメッシュを使った座標変換です
・ボーンとジオメトリ 座標変換の共通点
・HLSLシェーダー スキニングの座標変換
・DirectXTK側で行う、ボーンの平行移動行列と同じくボーンの回転行列の座標変換処理
の概要
ボーンとジオメトリ 座標変換の共通点(どちらもアフィン変換を使う)
実装のコア抜粋
cbuffer BoneMatrices : register(b0)
{
float4x4 g_BoneTransforms[64];
};
// 修正: C++側の SceneCB の構造に合わせる
cbuffer TransformUBO : register(b1)
{
float4x4 g_World;
float4x4 g_View;
float4x4 g_Projection;
};
ボーンを操作するには座標変換が必要です
座標変換と言えば、たいていは定数バッファからのバインドですね
PS_INPUT main(VS_INPUT input)
...
float4 transformedPos = mul(float4(input.pos, 1.0f), g_BoneTransforms[id]);
totalPosition += transformedPos.xyz * weight;
ボーンを変形するために、入力された頂点
struct VS_INPUT
{
float3 pos : POSITION;
float3 norm : NORMAL;
float2 texCoord : TEXCOORD0;
uint4 boneIds : TEXCOORD1;
float4 weights : TEXCOORD2;
};
の
float3 pos : POSITION;
と
cbuffer BoneMatrices : register(b0)
{
float4x4 g_BoneTransforms[64];
};

このプログラムでの、このアルゴリズムのイメージはこれです(かなり誇張されていますが)
怪人ドクロスケスケ男が折り紙を折ってます
そこに
totalWeight += weight;
ボーンにウェイトを加算しています。
つまりメッシュをボーンにどのくらい追従させるか?
(簡単に言えば骨に肉がガッチリつくのか、それともほろほろなのか)
を計算します。
float4 worldPos = mul(float4(totalPosition, 1.0f), g_World);
float4 viewPos = mul(worldPos, g_View);
output.pos = mul(viewPos, g_Projection);
最後におなじみシーンへの座標変換です
座標変換を知らなければ、こちらで異次元空間にとらわれたパンダを憐れみながら理解しましょう
https://qiita.com/YKVKDX12/items/35392b9eaae784b39bee
DirectXTK側は?
DirectXTKでも下準備の座標変換を行います
// 目標への平行移動
XMFLOAT3 d;
d.x = target[i].x - orig[i].x;
d.y = target[i].y - orig[i].y;
d.z = target[i].z - orig[i].z;
// 時間応じた回転(各ボーンで異なる速度)
float angle = elapsedTime * (0.3f + 0.15f * static_cast<float>(i));
// ピボット周りの回転 + 移動
XMMATRIX T_negPivot = XMMatrixTranslation(-pivot.x, -pivot.y, -pivot.z);
XMMATRIX R = XMMatrixRotationZ(angle);
XMMATRIX T_pivot = XMMatrixTranslation(pivot.x, pivot.y, pivot.z);
XMMATRIX T_move = XMMatrixTranslation(d.x, d.y, d.z);
XMMATRIX m = T_move * (T_pivot * R * T_negPivot);
XMFLOAT4X4 xf;
XMStoreFloat4x4(&xf, XMMatrixTranspose(m));
boneTransforms[i] = xf;
フルコード
https://github.com/kantamRobo/DirectXTKAssimp/tree/master/DirectXTK_Skinning
