three.jsで遊んでみる(31)

 プログラム,
 公開日:2014年9月21日 / 更新日:2014年10月22日

とあるモデルでのモーションの挙動がオカシイということで調べてみた所、
どうやら「付与」がうまく行ってない感じ。
付与に関してはうまく行っているようでダメな場合があり、
よく分からない状況だったりしました。
ところが先日色々いじくってたら、
なんかうまく行くようになりました。

当初は素直に、
対象ボーンをA、参照するボーンをBとして、
Aの変形量 += Bの変形量 × 付与率
とやったりしたのですが、どうもうまく行かない。
次に、
ある描画フレームとその次のフレームでの変形量の差分を求めて、
Aの変形量 += Bの変形量の差分 × 付与率
とやったらうまく行ったのですが、モデルによってはダメなことも。
そして今度は、
バインドポーズ時との差分でやってみたらイイ感じになりました。
バインドポーズ時の各ボーンの回転量はゼロなので、
当初のやり方でも回転に関しては間違ってないのですが、
バインドポーズ状態に初期化してないことが原因でした。
初期化してないので延々積算してしまっていました。
要するに初期化のし忘れ・・・でした(^_^;)

ということでまとめると、
1)各ボーンをバインドポーズ状態に初期化
2)Aの変形量 += Bの変形量の差分 × 付与率
を毎フレームやれば良い感じ。
実際には1)と2)の間で Bone Skinning とか IK とかをやります。
そして回転に関しては基準の回転量がゼロなので、
差分計算は省いても大丈夫なことになります。

「回転付与」に関してはおそらく解決だとは思いますが、
試すのに良さげなデータを持ってないため、
「移動付与」や「ローカル付与」は未検証です。
後で問題が起きるかも?(^_^;)

ということで改善後の動作テストを見るにはこららからどうぞ。
改善前はこららです。
確かにヒジの曲がりが直ってる感じです。

なお、テストでは以下のデータを使用させていただきました。
モデルはこちら、モデルモーションはこちら、カメラモーションはこちら

それから今回はもう一つ問題がありました。
“瞳”の表示がなんかオカシイ・・・。
調べてみると、透過オブジェクトの描画順に起因する問題でした。

ところで three.js では、
透過オブジェクトは奥から手前へ、
不透過オブジェクトは手前から奥へ、
の順で描画するようになっています。

透過オブジェクトの描画順については、
そのようにしないと矛盾が起きるのは理解しやすいと思います。
不透過については奥から手前でも問題ないのですが、
手前から奥にすると効率がよくなります。
奥行きを表すZバッファの値を比較することで、
実際の描画量を減らせる効果を期待できるからです。

明示的に透過指定のあるマテリアルや、
テクスチャが透過成分を含むマテリアルの場合に、
透過フラグを指定するように今までやってました。
大抵のモデルではそれで問題は起きない感じなのですが、
一部のモデルではうまく行かない場合があるようです。
そこで、
全マテリアルの透過フラグを強制的にオンにする機能を追加して、
透過問題に対応できるようにしました。

でも、よく考えてみると、
材質モーフとかで透過度が変化することは十分ありそうなので、
描画効率が落ちるかもしれないけど
デフォルトでオンにしてしまった方がよさそうです。
透過になるかどうかは静的ではなく動的にならざるをえないので、
それに対応できるようにしないとうまくない感じですね。
ただ現状では頂点モーフしか対応してなかったり・・・(^_^;)
それ以外の種類のモーフはいずれどうにかしたいですね。

タグ: ,

コメント投稿