スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

頂点ブレンディングをやってみた(DirectX)

【リンク】 ◆解説系TOP◆
今日は、頂点ブレンディングをやってみました。

この頂点ブレンディングというのは、スキンメッシュアニメーション
使ったりするのですが、 自分はやり方が良く分からないので自前で計算してました。

だって頂点ブレンディングに関する参考書が少ないんですよ。

まぁ、それはともかく今日 ソースコードを書いて上手く実行できたので、
ソースコードを含め 頂点ブレンディングについて書こうかと思います。



で、解説へ入る前に
頂点ブレンディングについての説明をします。

頂点ブレンディングというのは、要するに
-----------------------------------------------------------------------
1つの頂点に対し、複数の行列を影響させてみよう
-----------------------------------------------------------------------
と言うことです。



例えば、下記の行列2つがあるとします。
----------------------------------
    行列        影響度
----------------------------------
X軸に4移動させる行列   0.5
Y軸に2移動させる行列   0.5
----------------------------------


この場合、通常ならば頂点に影響を与える行列は1つのみなので
--------------------
・X軸に4移動させる
・Y軸に2移動させる

--------------------
このどちらかしか出来ません。

しかし、影響度を設定して複数の行列を適用させるようにすると、
上記の場合、2つの行列の差分を混ぜて頂点を動かせるようになります。

今回はどちらも影響度が0.5なので、
----------------------------
X軸に4 × 0.5 = X軸に2
Y軸に2 × 0.5 = Y軸に1

----------------------------
つまり頂点をX軸に2、Y軸に1動かすことが出来ます。
2つの行列が半々ずつ反映される。)

↓詳しくはコチラの方にも書いてあります。
【参考URL】スキンメッシュアニメーションの解説4



【頂点ブレンディングをやるための手順】
-------------------------------------------------------------
【1】頂点ブレンディングを有効にする。
【2】影響度を含めた構造体を定義する。
【3】SetTransform関数で、複数の行列をセット。
【4】SetFVF関数で、頂点データのタイプを通知。
【5】DrawPrimitiveUP関数を呼ぶ。

-------------------------------------------------------------

【1】頂点ブレンディングを有効にする。
まず、頂点ブレンディングを有効にする必要があります。
これには、SetRenderState関数を用います。
g_pD3DDevice->SetRenderState( D3DRS_VERTEXBLEND, D3DVBF_1WEIGHTS );

上記では、2つの行列による頂点ブレンディングを有効にしています。

D3DVBF_1WEIGHTSだから行列1つの重みしか設定できないのでは?
(2つの行列による頂点ブレンディングは出来ないのでは?)

と思うかもしれませんが、これは問題ありません。

行列A、Bがあり 行列Aの影響度を0.7とした場合、
行列Bの方は影響度を設定していなくても
1.0 - 0.7 = 0.3という風に自動計算してくれるようです。

よって、
----------------------------------------------------------------------
影響度を1つだけ設定する = 2つの行列の影響度でブレンディング出来る
----------------------------------------------------------------------
という事になります。

またD3DVBF_1WEIGHTS 以外のフラグも設定できます。
下記のページに詳しく書いてあります。
【参考URL】D3DVERTEXBLENDFLAGS 列挙型


【2】影響度を含めた構造体を定義する。
struct MY_VERTEX{
float px, py, pz; //頂点座標
float weight1; //重み(影響度)
DWORD color; //頂点色
};

影響度を含めた構造体を定義します。

ただし、この構造体の定義の仕方には順番があって、
影響度はRHWの後、法線定義の前に定義しないといけません。

詳しくはコチラに書いてあります↓
【参考URL】頂点フォーマットの順番


【3】SetTransform関数で、複数の行列をセット。
まず、ブレンディングしない場合は
下記の様にD3DTS_WORLD マクロを使って行列をセットします。
-----------------------------------------------------
g_pD3DDevice->SetTransform(D3DTS_WORLD, &mat);
-----------------------------------------------------

しかし、ブレンディングする場合は
D3DTS_WORLDMATRIX マクロを使います。
このマクロは、カッコつきで最後にインデックスを指定します。
g_pD3DDevice->SetTransform(D3DTS_WORLDMATRIX(0), &mat);
↑こんな感じ。

今回は2つの行列でブレンディングする訳ですが、
2つの行列にはそれぞれ0番、1番のインデックスが割り振られます。

※構造体で影響度を設定した方が0番
 1.0 - 影響度 で影響度が自動算出される方が1番です。


例えば下記の様な場合、

【行列】
X軸に4移動させる行列・・・mat
Y軸に2移動させる行列・・・mat2

【影響度】
MY_VERTEX v[] = {{-1.0f, 2.0f, 0.0f, 1.0f, 0xffff0000},
{ 1.0f, 2.0f, 0.0f, 0.5f, 0xff00ff00},
{ 1.0f, 2.0f, 0.0f, 0.0f, 0xff00ff00},
/* 以下略 */ };

【行列をセット】
g_pD3DDevice->SetTransform(D3DTS_WORLDMATRIX(0), &mat);
g_pD3DDevice->SetTransform(D3DTS_WORLDMATRIX(1), &mat2);

それぞれの頂点はこのように動きます。
--------------------------------
頂点0番はX軸に4
頂点1番はX軸に2、Y軸に1
頂点2番はY軸に2

--------------------------------
※行列を何もセットしなかった場合は、
(SetTransform関数を一切呼ばなかった場合は)
全て単位行列として判断されるようです。


【4】SetFVF関数で、頂点データのタイプを通知。
そして通常の描画方法と同じく、
どんな頂点データを描画しようとしているか?を伝えなければなりません。

定義した構造体は頂点座標と、影響度1つと、頂点色の3つであり、
それぞれのフラグはD3DFVF_XYZD3DFVF_XYZB1D3DFVF_DIFFUSEです。

なので、↓このように設定すれば良いとおもいますが、
#define MY_VERTEX_FVF  ( D3DFVF_XYZ | D3DFVF_XYZB1 | D3DFVF_DIFFUSE )
g_pD3DDevice->SetFVF(MY_VERTEX_FVF);
影響度を設定するフラグ(D3DFVF_XYZB1)は、 頂点座標のフラグも兼ねているっぽいです。


つまり、下記の様に頂点座標のフラグは外してOKです。
#define MY_VERTEX_FVF  ( D3DFVF_XYZB1 | D3DFVF_DIFFUSE )
g_pD3DDevice->SetFVF(MY_VERTEX_FVF);



【5】DrawPrimitiveUP関数を呼ぶ。
最後はDrawPrimitiveUP関数を呼んで終了です。
呼び出し例↓
g_pD3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 6, v2, sizeof(MY_VERTEX));
※DrawPrimitiveUP関数については、以前の記事で詳しく書いています。↓
【参考URL】DirectX描画方法まとめ


で、サンプルコードについてですが、影響度を設定したポリゴン
Z軸方向中心に0~90°回転するようになっています。
↑と↓キーで、影響度の有り無しを切り替えられるようになっているので、
動き方の違いが分かると思います。

【ソースコード】Blending.txt


あ・全然関係無いのですが"Garden of Eden"って曲良いですよね。
ライアーゲームの曲の中で一番好きです。 Garden of Eden
スポンサーサイト

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

コメント
コメントの投稿
管理者にだけ表示を許可する



上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。