LightWave3Dでテクスチャアニメ

前回から随分と久々の更新になっちゃったな。
まあ小説書いてる時はブログの更新ができなかったりするから、今回だけってわけでもないんだけど。

最近何やってるかというと、FlashのAway3Dという3Dフレームワーク上でモデルなんかを出す実験をしてます。Away3Dはフリーウェアで、主に海外の有志で開発されてるみたい。
厳密にはAway3D自体もAdobeから提供されているFlashのStage3Dという3Dライブラリを使ってます。
Flashっていうことは、ブラウザで動くっていうこと。つまり、ブラウザで3Dのリアルタイムレンダリングができたりするわけです。しかも基本タダで。
尤もスマホで動かすにはAIRとかで動くようにしないといけなくて、ぼくが作ってる範囲ではまだAIRで動くところには至ってないんだけど。最終的にスマホで動くようにするかは、わからない。現時点では実験なんで。

11月からAway3Dを触り始めて、リジッドモデルをOBJで出力して表示するとこくらいまではFlash側のプログラミングでなんとかなっていたんだけど、ボーンでアニメーションさせたりゲームに必要なデータを揃えていくには、オーサリングの時点でいろいろ準備しないといけないものが出てくる。例えばマップ上に配置物を置いて行ったりするのもFlash上でやるものではないよね。
ぼくは3DのツールはLightWave3Dしか持っていないんで、LightWave3Dで必要なものを出せるようにプラグインをいくつか作ってます。
モデルそのものとボーンアニメーションデータをファイル出力するモデルエクスポータは基本的な部分はできました。
顔の表情はテクスチャアニメ(動的テクスチャ)でやりたいな、と思って、まずはLW上でプラグインを作ってオーサリングまでできるようにしてからエクスポートしようと考えました。

6頭身ユミの3Dモデルをテクスチャアニメに適用させたスクショ。(VPRのプレビューを吐き出したもの。)
画像


テクスチャはベースとパーツ4枚の計5枚で構成。
画像

もっと詰め込んだほうが枚数は少なくなるけど、まぶたの中1だけっていうのはずいぶんと少ないし、口のパターンもこれだけじゃ全然足りないんで部位ごとに分けてます。
「目の周辺」は、ベースの上に瞳を書き込んだ後に重ねて目の形になるようにするためのマスクみたいなもの。今回は頬と一体化しちゃってるけど、本来は頬と目の下の部分は動くので分ける必要がある。目のハイライトも動かないのでここに入れてる。

Flashだと動的テクスチャはBitmapDataにオフスクリーンで書き込む感じになります。Stage3DはBitmapDataをテクスチャとして使える(2のべき乗サイズという制限はあるけど)ので、FlashのSpriteとかMovieClipとかが使えて割と柔軟性がある。今回は顔のパーツはBitmapDataに書きこんで、それをテクスチャとして使うわけです。

LightWaveでは柔軟性と実用性を考慮してノードでやることにしました。
画像

ずらーっと並んでてうわーって感じだけど、右目と左目があったり重ね合わせするんでこんな風になっちゃう。BA_AnimImageっていうのが今回作ったプラグインのノードで、「キャンバス(Canvas)」という画像の描画領域にそのノードが受け持つビットマップを指定の位置に書きこんで、次のノードのキャンバスに送るかColorから最終的な色を出力するのが基本的な機能。PatternX/Yはビットマップ上のどの位置のパーツを拾うかを指定するコネクションで、ここにNullの回転値なんかを繋いでやれば、Nullを表情のコントローラとして使うことができる。例えばまぶたの中割りをいくつか作ってあげれば滑らかに瞬きさせることも可能。
DestinationX/Yはキャンバスのどこに書きこむかっていうコネクション。視線を動かしたりする場合はここに繋いでやる。
今回は右目と左目のDestinationにボーンの回転値を入力し、まぶたと口のPatternにはNullのRotationのチャンネルを入力して、ボーンで曲げるのと同じ感覚で制御できるように組んでます。

レイアウトの画面。
画像

動的テクスチャなんで、通常のプレビューではノードの結果が反映されず左のようにベースだけ(というか実際には置き換えられるのでノード適用前のテクスチャ)が表示されてます。やりようによってはノードの結果を入れらるかも知れない。(キャンバスの最終状態を動的テクスチャに書き出し、それをノード適用前のテクスチャとして選択する感じ。)

BA_AnimImageノードの設定パネル。
画像

コネクションに比べると随分とパラメータが多いのが分かる。
キャンバスは一番最初のノードはベーステクスチャを貼り付けることができる。テクスチャを使わずに単色で塗りつぶることができて、その辺のパラメータが並んでる。まあ大抵はベーステクスチャを使うけどね。
Patternなんちゃらはパーツ画像の位置とかサイズ、入力値のスケーラなんかのパラメータが並んでいる。
Destinationなんちゃらはパーツの書き込み先にに関するパラメータ。スケーラとかオフセットは、Mathノードを入れなくてもある程度入力値を調整するために設けてます。実際これだけでもなんとかなる。
あ、あとAlphaはパーツを書き込む際の透明度ね。
HorzAlign/VertAlignは、パーツを中央揃えする。パーツによっては中央揃えのほうが便利なものがあるからね。
HorzReverse/VertReverseはパーツを左右または上下に反転する。これがあれば右目と左目のパーツをいちいち用意する必要がない。
Clipは書き込み先をクリッピングするもの。パーツを書き込む時に余計なところにはみ出さないようにするためのもの。

そして、PatternFileというのがキモ。テキストで記述したパターン定義ファイルを指定できる。
設定パネルではパーツのサイズは固定なんだけど、パターン定義ではパターン1つ1つのサイズが変更できて、Destinationにもオフセットが指定できる。
パターンはこんな感じで記述されている。

[
{ y_range_max:10, x:0, y:0, width:187, height:106 },
{ y_range_min:10, y_range_max:20, x:0, y:106, width:187, height:106 },
{ y_range_min:20, x:187, y:6, width:187, height:142 }
]


PatternX,PatternYのノード入力に対して、それぞれ一定の範囲にある場合に特定のパターンが選択されるように、x_range_min/max、y_range_min/maxを設定する。上記はまぶた用のパターンで、まぶたは3つのパターンが用意されていて、10度未満、10度~20度、20度以上の時に各パターンが選択されるように設定してある(今回はx_rangeは使っていない)。
x,yは改めてパターンの位置を定義するもので、width,heightはパターンのサイズを定義する。あとdest_ofs_x/yっていうので書き込み位置を調整できるけど、今回は使っていない。どのパターンもDestinationX/Yの位置を始点として書きこまれる。

この辺を駆使してできたものがこれ。VPRのプレビューを保存したものなんでちょっと小さいのはご勘弁。


どうすか。
まぶたは中割りが1しかないんでちょっとアレだけど、視線が滑らかに動いていて、のっぺらぼうに1枚テクスチャ貼りつけてるだけにしては割と違和感なく見えてると思います。
まあのっぺらぼうなんで、見る角度によってはそれなりだけど。


このプラグイン、もともとはFlashで使うデータを書き出すためのものなんで、これからエクスポート機能をつけないといけない。そしてFlash側に出力された情報を再生する機能をつけなくちゃいけない。
まだまだ完成は先。

プログラミングしながらモデリングもしながらってやってるとだいぶ時間がかかってしまうんで、あんまりやりこまないつもりです。
もともとFlash弄りだしたのは、小説(お話)と3Dモデリングを連動させてリアルタイムで動かせないかなーと思ってやりだしたのと、巷ではUnityとかもあって、この辺で3D押さえとかないと世間の波に取り残されるかなーと思ったのが動機なんで、プログラミングばっかりだと他のことが進まなくなっちゃう。技術的な部分と知識ベース(ノウハウ)があれば、いざっていう時にすぐ動けるんで、その辺を揃えるのが当面の目標。
とはいってもやりかけでやめちゃうのはいい加減すぎるんで、せめて水着のユミとか女の子モデルがプールサイドを練り歩くのを視姦するアプリくらいまでは仕上げたいなと思ってます。

Flashで動くものは以下のリンクに随時上げていく予定です。
http://cgi.geocities.jp/tsutsujiy/lightning/

"LightWave3Dでテクスチャアニメ" へのコメントを書く

お名前
メールアドレス
ホームページアドレス
コメント