note.x

Away3D 3.6リリース。

Away3D 3.6.0: Flash 10 upgrades and the Influxis Battlecell API

実質、3.5.3リリース時の仕様をそのまま引き継ぐ形でメジャーアップグレード。予告通りNumber3D廃止、めでたくネイティブ 3D APIに完全移行。FlashPlayer9向けの2.x系は、メンテナンスアップデートのみ行われていくことになる模様。個人的には面白味が減ってしまった。

今回のデモは、FMSのホスティングやってるInfluxisと組んでRTMFP使ったマルチプレイヤーのFPS。4人まで同時接続できるらしいんだけど、海外サーバーな所為か2人でもうゲームにならなかった。趣旨と関係ないけど、マウスドラッグでエイミングはやりにくいな。

放置しっぱなしの過去エントリをどーするかねーと思いつつ、とりあえずView3Dに関するエントリを修正。


Away3DのFlashPlayer10版が大きく仕様変更して、MatrixAway3Dクラスが廃止。ビルトインクラスのMatrix3Dに置き換わった。なので、Object3Dのtransformプロパティの各要素を直接書き換えたりするような実装してる場合はMatrixAway3Dに関わる部分を変更しないとビルドできない。MatrixAway3DとMatrix3Dの各要素は下記の対応づけ。

MatrixAway3D

MatrixAway3D.sxx MatrixAway3D.sxy MatrixAway3D.sxz MatrixAway3D.tx
MatrixAway3D.syx MatrixAway3D.syy MatrixAway3D.syz MatrixAway3D.ty
MatrixAway3D.szx MatrixAway3D.szy MatrixAway3D.szz MatrixAway3D.tz
MatrixAway3D.swx MatrixAway3D.swy MatrixAway3D.swz MatrixAway3D.tw

ビルトインMatrix3D

Matrix3D.rawData[0] Matrix3D.rawData[4] Matrix3D.rawData[8] Matrix3D.rawData[12]
Matrix3D.rawData[1] Matrix3D.rawData[5] Matrix3D.rawData[9] Matrix3D.rawData[13]
Matrix3D.rawData[2] Matrix3D.rawData[6] Matrix3D.rawData[10] Matrix3D.rawData[14]
Matrix3D.rawData[3] Matrix3D.rawData[7] Matrix3D.rawData[11] Matrix3D.rawData[15]

値を読み取るだけなら、

var tx:Number = Object3D.transform.tx;

という記述を、

var tx:Number = Object3D.transform.rawData[12];

に置き換えることで対処できる。

要素の値を変更する場合、MatrixAway3Dの要領で

Object3D.transform.rawData[12] = 100;

なんて感じで直接代入しても変更が反映されないので、

var vec: Vector.<Number> = Object3D.transform.rawData;
vec[12] = 100;
Object3D.transform.rawData = vec;

と、Matrix3Dの仕様に準ずる。

また、MatrixAway3Dで実装されていたメソッドの

  • quaternion2matrix
  • compare

と、ゲッター/セッターとして定義されていた

  • forward
  • up
  • right

は、Matrix3DUtilsという新クラスが引き継いでる。
forward, up, rightについては読み取り専用でそれぞれ

  • getForward
  • getUp
  • getRight

というメソッドに変更になった。

あと、ベクトルについても主要な部分はNumber3DからVector3Dへ移行してる。
まだ一部でNumber3Dが使われている部分があるけど、最終的にはなくなるみたいなのでNumber3Dは忘れてよさげ。Number3Dに実装されてたgetAngleメソッドは、新クラスVector3DUtilsが引き継いでる。

今回の仕様変更がどの程度影響してるのか分からんけど、じわじわと高速化してきてうれしげ。新機能いらないから洗練してほしい。

2010/09/16追記
とか言ってるうちに、FP10版3.5.4にアップデート。
ArrayをVectorに置き換えたりという地味な最適化を目的としたものみたいだ。


自前エンジンにラスタライザ組み込んだ。やっと一息つけるとこまでできたー。

Rasterizer Test01(要:FlashPlayer10.1)

解像度640×480、△9800のトーラスにフラットシェーディングした状態で、自分の環境の場合30fpsくらい。背面カリングしてるので、実質△4000〜△4500くらい描画してる。ポリゴンあたりの描画面積のほうが影響ありそうなので、何枚描画できるかなんて性能評価の基準にならないかもしれないけど、まあ目安として。初代プレステが(たぶんローレゾで)30フレーム動作だと12000微少ポリゴン描画できるってことだから、なんとか近づけたい。目指せ初代プレステ。

Zバッファ持たせたので交差ポリゴンも問題なし。

Rasterizer Test02(要:FlashPlayer10.1)

テクスチャにもとりあえず対応。アルファブレンドはまだ。

Rasterizer Test03(要:FlashPlayer10.1)

ようやくBlenderローダーが前に進められそうな状況が整ってきたので、とりあえずハデな部分はこのへんで止めて地味な処理を詰める。勝手な解釈で曖昧にしてた部分が全部ひっくり返されて、かなり整理された。


FrustumClipping と QuadrantRenderEngine が混在できないバグが未だにほったらかしっぽいので(Rev.942)、去年MLで流れてた対処法を紹介。とりあえず何とかしたい人向けTips。

FrustumClipping and QuadrantRenderEngine work together Demo(要:FlashPlayer9)

/core/dyn/DynamicTriangles.as の64行目以下

triangle.instance = object;
triangle.vertices = [v0, v1, v2];
triangle.uv = [uv0, uv1, uv2];
…

の部分を、以下のような感じに。

triangle.renderCommand.instance = object; //←この一行を追加
triangle.instance = object;
triangle.vertices = [v0, v1, v2];
triangle.uv = [uv0, uv1, uv2];
…

バカ正直に使うと当然負荷が大きくなるわけで、床面が真っ平らで良いならビットマップを透視投影した方が経済的だと思う。
QuadrantRenderEngine使用時は、通常のクリッピングの流れからバイパスして、視錘台の各平面と他のポリゴンとの交差をいっぺんに判定して分割、不可視部分を刈り取るようにすれば結構最適化できそうだけど、そこまでやるなら根本的なデータ構造含めて作り直したいっていう開発サイドの判断で放置されてるのかなぁ。


Away3Dに BSP/PVS を実装しようとしてるブランチを見つけてニヤリ。
コミッターはFP10版Away3DにPixelbenderによるシェーディング実装した David Lenaerts
今どきのリアルタイムレンダリングシーンじゃ特に意識しないだろうし、Flash用エンジンに絞っても Alternativa3D とか infinity3d にはとっくに実装されてるし、これといったアドバンテージがあるわけじゃないけど、ライセンス的に緩めなAway3Dに組み込まれるのは本当にありがたい。

今のところObjectContainer3Dを継承したクラスとしてBSPTreeが実装されてて、空間分割されたコンテナをSceneに追加する形で使う。この辺はハナっからScene3DにBSPが組み込まれてる(と思われる)Alternativa3Dのほうがスマートだと頭の悪いオレでも思うので、今後の仕様変更でScene3Dに内包されるかも。そうなれば Zソート・クリッピング・カリング・ポリゴン交差時の分割処理に至るまでパイプラインの至る所で恩恵にあずかれるはず。あと、内部で持ってる物理演算や衝突判定の最適化にも取り入れようとしているみたいなので、ちょっぴり期待しておく。

まだまだガンガン仕様変更があると思うけど、どんな感じになるのか試したくて、以前作った迷路を使ってポータルシステムがどの程度カリングを最適化してくれるのかを見てみた。比較用にBSP/PVSを使わない場合も改めて作成。

BSPTreeとポータルの生成にはかなり時間がかかる。DoomやQuakeなんかだとレベルエディタを使って事前に作ったものを外部ファイルとして保存しておいて、実行時は読み込みだけで済むようにしてあるように、事前処理のがよさそう。Away3Dもこの辺は考えてあるようで、エクスポータークラスが用意されてる(PreFabにレベルエディタ的な機能が追加されたりして?)。今回は使い方がよくわかんねーのと、必要なデータ全部エクスポートするのこれ?って感じだったので諦めた。

Maze normal
Maze using BSP/PVS (BSP/PVS使用)

■操作方法
カーソルキー [CursorKey] … 移動 (move)
[Z], [X] Key … ティルト (Tilt)

※要:FlashPlayer10

BSP/PVS版は、スタンドアロンプレーヤーならかなりヌルヌル動く感じ。マシンパワーのある環境だと2つの違いが分かりにくいかもしれないけど、オレの環境(MacBookPro 2.33GHz Core2Duo)だと全然違う。クリッピングモードをRectangle Clippingにすると視覚的にも違いが見て取れる。Project stats の T-ELEMENTS と R-ELEMENTS を見ると処理対象のFaceが大幅に減ってるのが分かる。ワクワクしてまいりました。

ハードウェアの進化に伴って失われつつある先人達の技術を追体験しつつ手軽に勉強できるのが、ActionScriptで3Dをやる唯一のメリットだと思うので、こういうトピックは超アガる。ちゃんと自分のものにするには相当ハードル高いけど、とりあえず周辺をウロウロする。

参考:
BSP Trees(視覚的でわかりやすい)
バイナリ空間分割(Binary space partitioning)- Wikipedia
BSP trees in 3D worlds
ゲームプログラミングのためのリアルタイム衝突判定(Amazon)


mozOrientation + PV3D(要:FireFox3.6 + Flash Player9以降 + 加速度センサ付きPC)
※加速度センサ積んでれば、PCを前後左右に傾けることで玉が転がる

FireFox3.6が加速度センサの傾き検出できるってんで、ありがちな物を作って体験してみた。
自分のMacBookProでしか試してないんで確証はないけど、mozOrientationがディスパッチされる環境なら動くはず。

参考サイト:
加速度センサーの値を表示するサンプル(MozOrientation)

今回のネタを作ろうとFireFox3.6にしたらFlashの再生時、妙に負荷かかるようになった。
起動して数時間使った後で、上のデモを再生すると頻繁にGCが発生してるみたいな挙動になって、衝突判定すり抜けたりする。FireFoxを再起動すると直るんだけどオレの環境の問題かなぁ。


suumo(要:Flash Player9)

スーモ萌え。
を目指して作ったものの「スーモではない何か」が出来た。
無意味にファー表現したので、見た目のわりにポリゴン数食ってたり、負荷が増大してて非常にコストパフォーマンスが悪い。低コストな屋外の景観生成が個人的な課題。一つの方法論がドライブシミュもどきの時の構造だけど、これよりさらにコストを抑えられないもんかな。


Imitate Morphovision(要:Flash Player9)

※ステージドラッグで視点位置が変わります。

岩井俊雄さんと、NHK放送技術研究所が共同開発したモルフォビジョン
プリズムミラーで反射させたプロジェクタからの光を使ってスリットスキャンする方法で、立体物の見えを変化させるシステム。Another time, Another space の立体版って感じだけど、デジタル的な画像処理じゃない方法で摩訶不思議な現象を作り出してるのがカッコイイ。悔しいかな一度も本物を見た事がない。

んで、実機と同じような状況を作ったら、以前作ったゾートロープのようにソレっぽく見えたりしねぇかなぁーとか思ったのが2年くらい前。エライ時間がかかったけど、プロジェクションマップがそれなりに動いたので、技術的に課題だったライトマップ的なものが実装できて、ようやく動かせた。見やすくするためにブレンド使った以外は、スリット光の移動と物体の回転しかしてないんだけど、歪んで見えないことも…ない感じにはなった。スリット光のピッチが荒いのと、回転と同期がうまく取れてないあたりが課題か。でもまぁ、明らかに普通に回しただけじゃこうは見えないので、ちょっと嬉しい。

実機みたいに滑らかで有機的な振る舞いをさせるには、もっと高fps叩き出せるプラットホームじゃないと無理があるかなぁ…。それとも根気よく調整すればもう少し改善するのか? とりあえず一歩前進。なんとなく可能性が垣間見えたので、またしばらく寝かせとこう。


projectionmap

Projection map Test(要:FlashPlayer9)
※各Cubeはドラッグで動かせます。

プロジェクションマップの習作。
パフォーマンス悪いなぁ。根本的に考え直さないとダメか。


3Dアプリでモデリング・モーション付やって、それをそのままASで扱えたらさぞかし楽しかろうと常々考えてきたにもかかわらず、一向にベストな方法が見つけられないし、出現しそうもないので、自力で色々作り始めてみることにした。

本来、.daeが正しく書き出せて、正しく読み込まれればそれが出来るはずなんだろうけど、現状3dsMAXとかMayaでも持ってない限り可能性が薄い。Unwrap3Dはwin用だし。んで、BlenderのエクスポータでもいじってみようかとColladaの仕様書とか見てみたりするんだけど、これがもーなにがなんだか。

そんなわけで.blend形式。ファイルフォーマットが公開されてるんで、こいつを手がかりに.blendローダーを作成。バイナリ最高。バージョンによるデータの差異は吸収できてないしメッシュの読み込みだけだけど、2.49bのファイルは問題ないとこまで来た。
いいかげんな3Dエンジンらしきものも自作。ジオメトリパイプラインの実装でつまずきまくって、首吊ろうかと思ったけど何とか動くようになった。まだ何かがオカシイので多分どっかの符号間違えてる。苦労した分、オレオレエンジンの成長が楽しくてしょーがない。擬人化したいぐらい。

ここまでの成果として、Blenderで編集したメッシュが.swf側に即時反映されるビューアを作ってみた。画面右がFlashPlayer。

城戸さんそのまんまなのがアレだしショボすぎて泣けてくるけど、これ、ちゃんと作ればかなり便利かも。swfで実際に表示されるまで分からない部分とかが、モデリングしながら確認できるのはメチャメチャ助かる。

当面は、プレハブみたいな実装の3Dエンジンをもうちょっとマトモなものにしつつ、なんとかしてモーションデータの再生までこぎ着けたい。とか宣言して自分を追い詰めておく。
まぁぼちぼち。