「スケルタルアニメーション」の版間の差分
Administrator (トーク | 投稿記録) |
Administrator (トーク | 投稿記録) |
||
(同じ利用者による、間の6版が非表示) | |||
5行目: | 5行目: | ||
スケルタルアニメーションでは「時間ごとのボーンの移動量や回転量」というデータだけを記録しておき、再生時にメッシュの変化を計算してやります。ボーンは階層構造になっており、親ボーンからの変化の相対値だけを保持するのが一般的です。 | スケルタルアニメーションでは「時間ごとのボーンの移動量や回転量」というデータだけを記録しておき、再生時にメッシュの変化を計算してやります。ボーンは階層構造になっており、親ボーンからの変化の相対値だけを保持するのが一般的です。 | ||
なお、ボーンというと人間や動物の「骨」というイメージですが、この技法は決して実際の解剖学や物理的なプロセスを模倣するものではありません。人体であれば本来なら曲がらない方向にも普通に曲がります。実のところ[[ノートパソコン]]の[[液晶]]の繋ぎ目やドアと壁を繋ぐ「ラッチ」みたいなものです。そのため「ドアの開閉」などにも応用できます。 | |||
== 主な用語 == | == 主な用語 == | ||
16行目: | 16行目: | ||
=== Bone Weight === | === Bone Weight === | ||
メッシュが保持する「ボーンとの繋がり」が複数に渡る場合の影響度を表します。一般的にBone | メッシュが保持する「ボーンとの繋がり」が複数に渡る場合の影響度を表します。一般的にBone Weight配列の合計は「1」になります。この値を使うことで関節付近のメッシュを変形する際におかしくなる現象を軽減できます。関節付近ではないメッシュでは特定のボーンにパラメーター全振りです。 | ||
[[バーテックスシェーダー]]ではだいたいこんな感じです。 | [[バーテックスシェーダー]]ではだいたいこんな感じです。 | ||
シェーダーで処理する場合は「ボーンとの繋がり」をvec4に収めたいので最大4個が定番です。別に4個でなくてもいいです。人体のボーンの場合は3分岐から4分岐くらいなのでまず問題になることはありません。 | |||
<source lang=c> | <source lang=c> | ||
// 定数バッファでボーン配列を渡す | |||
layout(set = 0, binding = 3) uniform BonesBuffer | layout(set = 0, binding = 3) uniform BonesBuffer | ||
{ | { | ||
mat4 BoneTransformations[ | mat4 BoneTransformations[32];//各ボーンの位置や回転などを格納した行列の配列 | ||
}; | }; | ||
// 頂点バッファに「ボーンとの繋がり」と「ボーンの影響度」を持つ | |||
layout(location = 0) in vec3 Position; | layout(location = 0) in vec3 Position; | ||
layout(location = 1) in vec2 UV; | layout(location = 1) in vec2 UV; | ||
layout(location = 2) in vec4 BoneWeights;// | layout(location = 2) in vec4 BoneWeights;// ボーンの影響度 | ||
layout(location = 3) in uvec4 BoneIndices;// | layout(location = 3) in uvec4 BoneIndices;// ボーンとの繋がり | ||
void main() | void main() | ||
41行目: | 43行目: | ||
} | } | ||
</source> | </source> | ||
== 関連項目 == | |||
* [[スキンメッシュ]] | |||
[[category: 3DCG]] |
2024年7月4日 (木) 01:34時点における版
スケルタルアニメーション(英語:skeletal animation)とは、3DCGにおけるアニメーションの手法のひとつで、キャラクターの内部に「骨(ボーン)」を持たせ、その移動や回転にあわせて表面のポリゴン(メッシュ)を変化させるというものです。
いわゆるスキンメッシュの技法のひとつですが、世間一般ではおおよそ「スキンメッシュ≒スケルタルアニメーション」となっています。
スケルタルアニメーションでは「時間ごとのボーンの移動量や回転量」というデータだけを記録しておき、再生時にメッシュの変化を計算してやります。ボーンは階層構造になっており、親ボーンからの変化の相対値だけを保持するのが一般的です。
なお、ボーンというと人間や動物の「骨」というイメージですが、この技法は決して実際の解剖学や物理的なプロセスを模倣するものではありません。人体であれば本来なら曲がらない方向にも普通に曲がります。実のところノートパソコンの液晶の繋ぎ目やドアと壁を繋ぐ「ラッチ」みたいなものです。そのため「ドアの開閉」などにも応用できます。
主な用語
Bone Transform
ボーンの位置や回転の情報を格納した行列です。複数ボーンの配列となっているのが一般的です。
Bone Index
メッシュが保持する「ボーンとの繋がり」を表すBone Transform配列のインデックスです。関節付近を適切に処理するため複数のボーンとの繋がりを配列として保持し、その影響度合いをBone Weightに格納します。
Bone Weight
メッシュが保持する「ボーンとの繋がり」が複数に渡る場合の影響度を表します。一般的にBone Weight配列の合計は「1」になります。この値を使うことで関節付近のメッシュを変形する際におかしくなる現象を軽減できます。関節付近ではないメッシュでは特定のボーンにパラメーター全振りです。
バーテックスシェーダーではだいたいこんな感じです。 シェーダーで処理する場合は「ボーンとの繋がり」をvec4に収めたいので最大4個が定番です。別に4個でなくてもいいです。人体のボーンの場合は3分岐から4分岐くらいなのでまず問題になることはありません。
// 定数バッファでボーン配列を渡す
layout(set = 0, binding = 3) uniform BonesBuffer
{
mat4 BoneTransformations[32];//各ボーンの位置や回転などを格納した行列の配列
};
// 頂点バッファに「ボーンとの繋がり」と「ボーンの影響度」を持つ
layout(location = 0) in vec3 Position;
layout(location = 1) in vec2 UV;
layout(location = 2) in vec4 BoneWeights;// ボーンの影響度
layout(location = 3) in uvec4 BoneIndices;// ボーンとの繋がり
void main()
{
mat4 skin = BoneTransforms[BoneIndices[0]] * BoneWeights[0]
+ BoneTransforms[BoneIndices[1]] * BoneWeights[1]
+ BoneTransforms[BoneIndices[2]] * BoneWeights[2]
+ BoneTransforms[BoneIndices[3]] * BoneWeights[3];
gl_Position = Projection * View * World * skin * vec4(Position, 1);
}