頂点シェーダでスキニングと頂点ブレンド 可変長の定数バッファ

頂点シェーダでスキニングと頂点ブレンドを行います。基本的な原理などは多くの場所で公開されているので省略、DirectX11での実装について説明します。
ボーンウエイト付のモデルデータは自作できないので、入手しやすいPMD/VMDファイルを使用します。

PMD/VMDの表示再生
PMD/VMDの表示再生

DirectX11でスキニング&頂点ブレンド

スキニングで一番問題になるのが変形処理用のボーン行列の数制限です。DirectX9などの頂点シェーダでは定数レジスタが少ないため、50行列ぐらいが限度でした。その制限のため、ポリゴンを分割して制限数を超えないようにしたり、テクスチャでボーン行列を受け渡ししていました。DirectX11(シェーダモデル4~)では定数バッファ1スロットあたり4096ベクトル(16byte)、最大4096/3=1365個の行列を転送できます。通常の使用方法では、制限が問題になることはないでと思います。余計な処理をしなくていいので楽だし、効率が良さそうです。
※ボーン行列はfloat4x4から不要な部分を除いたfloat4x3(3ベクトル分)を使用

可変サイズの定数バッファ

スキニングでのボーン行列は、モデルごとに異なるため定数バッファのサイズが変わります。毎回、最大個数分の定数バッファ更新すると効率が悪いので部分的な更新が必要になります。が、DirectX11では定数バッファの”明示的な”部分更新ができません。DirectX11.1では可能ですが現環境では未対応なので、解決方法を探します。

わざとサイズ不足のバッファ(ID3D11Buffer)を使用
頂点シェーダの定数バッファ定義には、最大数のボーン行列を用意。
ID3D11Device::CreateBufferで256行列より小さいバッファを作成、ID3D11DeviceContext::UpdateSubresourceで転送。データサイズ不足の転送になる。
これで正常に動作しました、簡単に終わったと思ったら
Debugビルドではこんなエラーが大量に

なんか動作が不安定と思っていたら、大量のエラーログが原因でした。エラーログには「サイズ不足と知って使用していた場合問題ありません」とあるのでこの方法で間違っていないようです。ですがエラーログを出したくないので回避方法を考えます。エラーログを出さないようにする(方法を知りませんが)のは、本当にサイズ不足の場合があるので却下。

逆に定数バッファをサイズ不足に その1
ダメでした。ただ思っていたのと動作が違う。BoneMatrix配列の範囲外にアクセスするため、行列が不定値になり表示がくずれるはずですが、すべてBoneMatrix[0]の値を参照しているような挙動になっています。エラーログの出力はなし。不思議に思って検証してみると[1]の配列の場合

頂点シェーダの仕様でしょうか、[]内に変数を使用した場合[0]に置き換わるような気がします。[1]の配列はただの変数に置き換わる?

逆に定数バッファをサイズ不足に その2

うまく動作しているようです。エラーログなし。定数バッファの範囲外も更新されているようです。ただし、ボーン行列が1つだとデータ不足エラーログが出力されます。定数バッファのサイズ<データ転送サイズ(ID3D11Buffer)の状態だと不安なので、さらに改良してみる。

packoffsetを使用
定数バッファの定義でpackoffsetを使用すると、定数バッファ内の場所やベクトル要素xyzwへの割り当てを指定できます。最終的に次のようになりました。

packoffset(c765)で必要な定数バッファサイズを確保。これで定数バッファサイズ>データ転送サイズかつ、エラーログなし。ただし、最適化などで未定義部分(c6~c764)の定数バッファの内容が更新されない可能性があるので注意しておく。今のところ問題はなさそう。

おまけ float4の配列で

行列1つでもエラーログが出力されませんが、余計な計算が必要になるため採用しません。ボーン行列が1つの場合、ダミー行列を1つ追加してエラーログ対策したほうが簡単。

サンプルプログラム

ダウンロード
スキニングと頂点ブレンド PMD/VMDの表示再生(一部の機能のみ)

PMD/VMDの対応について

一部の機能のみ対応しています。ただし、その対応も完全ではありません。スキニングと頂点ブレンドの検証用に利用しています。表示はテクスチャと輪郭線のみ、モーションはボーンとIKのみ対応。IKはかなり怪しいです。

サンプルデータ

サンプルプログラムにはPMD/VMDデータは含まれません。
sample_data.hに読み込みたいPMD/VMDのファイルパスを設定してください。

制作環境

Windows7 64bit SP1
Visual Studio Express 2012 for Windows Desktop Update2
Windows SDK for Windows 8 (2012/11/15)

リンクなど

PMD/VMDファイルの表示再生には、様々な解説ページ、公開データを利用させていただきました。貴重な情報やデータを公開している方々に感謝。

MikuMikuDance

VPVP

PMD/VMDフォーマット

MMDのモデルデータ(PMD)形式 めも (まとめ)/通りすがりの記憶

VMD再生のためのベジェ曲線計算

MMD on WebGL カメラとライトと表情のモーションに対応(あと補間曲線について)

スクリーンショットのPMDデータ

ままま式GUMIβ版

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

認証:数字を入力してください(必須) * Time limit is exhausted. Please reload CAPTCHA.