はかせのラボ

私の頭の中を書いていく雑記ブログです

DirectX12 ボーンオフセット行列と初期姿勢行列

あいさつ

どうも、はかせです。

今日はボーン勉強会その二です。

今回のテーマはボーンについて調べてるとしょっちゅう出てくる
ボーンオフセット行列
初期姿勢行列です。

ボーンオフセット行列

ボーンをローカル座標で原点に移動させる行列です。

なんでこんな行列が存在するかっていうと
ランタイムでの行列計算コストを減らすためですね。

仮にボーンを(2.0,1.0)から(1.0,2.0)へ移動させるとしましょう。
直接移動させることももちろんできます。
所詮(2.0,1.0)-(1.0,2.0)=(1.0,-1.0)となり
(1.0,-1.0)の移動行列を計算して適用すればいいだけですから。

ただ行列の計算ってのは
色んなとこでもさんざん言われているよう
結構重いです。
f:id:hakase0274:20191019164003p:plain

それを全頂点分やろうとすれば
フレーム落ちという結果が目に見えます。

なので登場するのがボーンオフセット行列です。
こいつはボーンを一旦原点を移動させる行列です。

原点へ移動させることで原点から
目的地への移動行列があるだけで
移動できるようになります。

そして大抵この目的地への移動行列ってのは
モデルデータやらアニメーションデータやらに入っているか
予め線形補間なりなんなりで計算して置けます。

ボーンオフセット行列は初期位置から原点(0.0,0.0)への移動行列なので
予め計算して持っておけます。

つまり移動に必要な行列を予め持って置けることになります
f:id:hakase0274:20191019165033p:plain

こうすることでランタイム中に行列の計算を
減らすことができるようになり、
パフォーマンスに貢献してくれます。
(もちろんケースバイケースなので完全0にはならない可能性もある)

初期姿勢行列

ボーン座標を親のローカル座標に変換する行列です。

先ほど述べたボーンオフセット行列を用いた移動は
あくまで自分のローカル座標上での移動です。

ボーンてのは必ず親が存在しており
相互に干渉しあうことで自然な動きを実現します。

つまり最終的な位置は親のローカル座標上で決定される必要があります。

それを実現するのがこの初期姿勢行列になります。
計算も結構簡単で子の初期位置に
親のボーンオフセット行列をかけていくだけです。

ボーンオフセット行列は
さっきも言ったように原点へ
移動させる行列です。

これを利用することで
親の原点からどれだけ移動しているか=
親のローカル座標上での座標が求められるわけです。

ボーンオフセット行列が原点からのオフセットであったのに対し
初期姿勢行列は親からのオフセットって感じですかね。

あとがき

今回はボーンを勉強していく中で何回も出てくる
ボーンオフセット行列と初期姿勢行列でした。

ザ・数学みたいな感じでしたね。
なんとなくわかった気になってますが
なんかもやっとした感じでもあるので
どっか間違ってるかもしれませんね。

間違ってたらやってく中で変に詰まるでしょうし
その時に改めて勉強しなおすだけですね。

今回の記事が良ければスターやコメント等よろしくお願いします。
それでは今回はこの辺でノシ

DirectX12 ボーンについて調べてみた話 ~そもそもボーンとは~

あいさつ

どうも、はかせです。
前回Lat式ミクさんの顔の異常を修正し
無事描画することに成功しました。

ただまだ完全とは言えませんね。
前回の記事でも少しだけ触れましたが
トゥーンレンダリングもできていません。

それに本来あるはずの影なんかもありません。
私の描画したミクさん
f:id:hakase0274:20191018161608p:plain
PmxEditorで見たミクさん
f:id:hakase0274:20191018161618p:plain
この辺の改良もしていかなければなりませんね。

ただ今回はその改良の話ではありません。

不完全とはいっても形だけは描画できたわけです。
形が出たら次は動かしたくなります。
ということで今回からは
ボーンアニメーションの実装をがんばってやります。

今回はまず
ボーンって何?
ってところからやっていきます。

ボーンとは

このミクさんについてる矢印っぽいもののことです。
f:id:hakase0274:20191018162342p:plain

Mayaとか触ってる人なら親しみがあるかもですね。
(私は苦手です)

こいつは何する奴かって言うと
頂点がどう動くかってのを指定する奴です。

世の中に存在するアニメーションってものの原理はパラパラ漫画です。
人間がまともに知覚できないほど高速で絵を切り替えることで
あたかも動いてるように錯覚させるわけです。

ゲームも1秒間に60回っていう超速で画面を切り替えることで
あたかも画面が動いているように見せています。

モデルのアニメーションも同じです。
相も変わらずパラパラ漫画よろしくの超速で
モデルの頂点を動かしメッシュを貼ることで
あたかもモデルが動いたように錯覚させるわけです。

ただここで問題が発生します。
一体この頂点の移動をどうやってやりましょう?

毎フレームの頂点情報を
全てデータで持っておいて
逐次読み出す?

頂点ってのは座標とか法線とか持っていて
1頂点だけで数十バイトは少なく見積もってもあります。

2D画像とかなら頂点数は4つで済むので
気にしなくてもいいですが、
3Dモデルの頂点数は1万とか2万とかいきます。

つまり1フレームの頂点情報だけで数十万バイトになって
それがアニメーションのフレーム分存在することになります。

最近のハードはメモリも結構増えてきてるので
耐えられるかもしれませんが
あまりやりたい方法ではないですね。

なのでこの案は没です。

じゃあ
特定フレームにおける
頂点情報だけ持って
間は補間で求める?

キーフレームアニメーションが
この手法ですね。

実際使われている手法ですし、
わかりやすいのでありっちゃありです。

ただ逐一場所を決め打ちで作るのはめんどくさいです。
この頂点はここであの頂点はあそこで・・・
なんてやっていたら時間もかかりますし、
ミスも増えますし、
アニメーションを変更したいってなった時に死に目を見ます。

どこに移動するかという結果ではなく
どう移動するかという過程で管理できるようになれば
何か変更とかかけるときにも
そこを修正するだけで済むので楽ですよね。

そこで登場するのがボーンです。

ボーンは
原点と回転を示すための点の二点で構成されています。
つまり自分がどこにいたのかっていう情報
自分がどう移動したかっていう情報が取得できます。

数学的にちょっと頭よさそうな言い回しをすると
点Aと点Bによって作られる線分ABです。
イメージこんなん
f:id:hakase0274:20191018170341p:plain

あとはこの動きと
頂点の動きを紐づければ
メモリ使用量も減らし
管理も楽にできるというわけですね。

あとがき

今回はボーンアニメーションをやるにあたって
避けては通れないボーンの話でした。

ぶっちゃけキーフレームアニメーション作るっつっても
最近のツールはボーンで操作できるので
ほぼボーンアニメーションなのかなとか思いました。

そして数学の塊だから一つ理解するのも
とても時間がかかります。
(商業高校出だからそもそもそんな数学やってない)

まぁゆっくり一歩ずつやっていきます。

それと話は変わるんですが、
PmxEditorって知ってますか?
私は昨日知ったんですけど
PMXだけじゃなくPMDも開けるんですね。

おまけにマテリアル情報とかまでしっかり見れる。
これの存在をもう少し早く知れていれば
昨日のCullMode切り替えてマテリアルの有無を調べるなんて言う
変な手段を取らなくて済んだかもしれませんね。

こちらのページからダウンロードできるので
自分でPMDやPMXの改造をやってみたいって方や、
私みたいに自前のプログラムで
出すための情報収集などに使いたいって方は是非
kkhk22.seesaa.net


この記事が良ければスターやコメント等よろしくお願いします。
それでは今回はこの辺でノシ