テレワークならECナビ Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!
無料ホームページ 無料のクレジットカード 海外格安航空券 海外旅行保険が無料! 海外ホテル


log

2010.03.06 C++:スキンメッシュはシェーダでやるべし

最近は色々な実装を平行して作業したりしていて、片手間に
固定機能パイプラインのスキンメッシュを試してみたのですが、
色々と試行錯誤した点が多かったので以下めも。
(横文字がいつもより多くて非常に読みづらいので注意です!)

今までCPU計算でスキンメッシュさせていたやり方に
SetRenderState()のD3DRS_VERTEXBLENDフラグと
D3DRS_INDEXEDVERTEXBLENDENABLEフラグを使用して、
D3DTS_WORLDMATRIXに各フレームのスキニング行列を
設定してみると固定機能パイプラインで描画できるかなと考えたんですが。。
デバッグ中に、「あんさんのPCはD3DRS_INDEXEDVERTEX
BLENDENABLEをサポートしとらんよ」っていわれてしまいました。

そこでデバイス作成時のオプションをD3DCREATE_HARDWARE_
VERTEXPROCESSINGからD3DCREATE_SOFTWARE_
VERTEXPROCESSINGに変更してインデックスつきで
スキンメッシュ描画が無事できるようになったのですが…重い。
重すぎるのです。。キャラ1体表示させるだけでも20fps
程度しかでない、つまり自前CPU計算より何倍も重いんですよ。

後からWEBで色々と調べてみたところ、どうやらDirectX9系の
グラボはシェーダで描画することを推奨しているので、MaxVertex
BlendMatrixIndex(最大ブレンドマトリックスインデックス数)が
0のグラボが多いそうです。。なので、「スキンメッシュやるくらいなら
シェーダ使いんさい!」ってことらしいです。

DirectX9系以前のグラボの場合はD3DRS_INDEXEDVERTEX
BLENDENABLEフラグを使って固定機能パイプラインで描画したり
したほうが安定するんでしょうけど、対応させようにも自分の
環境だとデバッグすらできませんからね。。

今までネットでスキンメッシュについて調べていて、「なんで
みんな描画時に複雑な分岐フラグを立てて描画してるんだろう」と
思ってたんですが、ようやく分かったような気がしました。

とりあえずシェーダ対応ならシェーダで計算、シェーダ未対応なら
自前CPUで計算という形でプログラムを組んでいこうと思います。