9 月 23 2008

PV3Dでレースゲーム制作 16 - 距離に応じたレンダリング切り替え

Posted by tanjo at 3:45 PM

カメラからの距離に応じて、近くは精密なモデルを、遠くの方はザックリとしたものを表示分けできるようにします。もちろん Papervision3D にそんな都合の良いピンポイント機能はありません! FrustumCamera3D のニア・クリップを活かしてなんとか再現します。

(訂正)
サーセン。大嘘でした。
PV3D 2.0 Beta 1あたりで追加された SimpleLevelOfDetail を使えばカメラからの距離に応じて3Dオブジェクトを切り替えたりできます。
しかし!残念なことにオブジェクト単位の判定しかできない模様。私のように環境全体を1つの3Dモデルで作っちゃってる場合には使えませんね。環境全部が一気に入れ替わってしまいますから。

SimpleLevelOfDetail については、ぽりGさんのブログにデモ付きの解説があります。
» flashゲーム作成記 | PV3D:Beta版の機能をいろいろ調べてみた

建物を増やすには

今のコースだとそれほど意味はないけど、市街地みたいなコースを作るにはかなり重要になってきそうです。(超広大3Dを実現しているゲーム「Grand Theft Auto」からヒントを得ました。なんて言ったら大げさかな。)

どういうことかちょっと詳しく書きますと…
現行( » 前回デモ)では以前のエントリで書いたように FrustumCamera3D (PV3D最新版では Camera3D に統合)を使ってファー・クリッピングすることで、巨大な3D空間を限られた処理内で実現しています。
でもこれだけだと、遠くからも見えて欲しい建物もパイロンのような小さなオブジェクトも、同じ距離で判定されてしまいます。市街地を作るにはある程度遠くの建物も表示する必要がありますが、そうすると細かいオブジェクトのポリゴン数がやたらと増えて、処理のネックになっちゃうわけです。

3次元クリップ&2次元合成

そこで、3Dオブジェクトのレンダリングを、「すべての要素を描画する近距離」、「アバウトでいいから大きな建物だけ遠くまで表示する遠距離」の2つに分けることにしました。
具体的には、Camera3D や Scene3D を複数使い分けることで実現します。たとえば…

距離 Scene3Dにあるオブジェクト Camera3Dのクリップ Viewport3D描画順
すべての要素を含む精細モデル near=10, far=22000 最後に addChild
大きなものだけを含む簡易モデル near=13000, far=40000 先に addChild

viewport同士の合成は2次元の処理になります。つまり、「中距離~遠距離をレンダリングしたレイヤー」の上に、「カメラすぐ~中距離までのレイヤー」を重ねたような状態です。2D合成でも距離の順序は保たれているから無問題!なお床面はこれらとは別に、1番最初に描画しています。

近カメラの far と遠カメラの near が同じ値じゃないのは、近・遠距離の間に描画抜けが出ないように調整したため。こんなに重複させないといけないとは。。。

文字の説明だとわかりにくかったですね。
こういう描画になっています。この3つを合成。

synthe

本来なら、(同じカメラを使って)3Dオブジェクトごとにどのくらいの距離まで表示させるか設定できれば良かったんですけどね、最近のFPSみたいな感じに。残念ながらPV3Dでそういう描画は無理そうだったので2D合成でカバーしました。
近距離/遠距離用で2種類のモデルを読み込まなきゃいけなくなるのは難点だけど、まず当面はパフォーマンスの確保が優先、と。

デモ

レースゲーム・デモ画面

» ゲームをプレイする (要:Flash Player 9.0.115.0以降)

このゲームのソースファイル Main.as はこちらから参照できます。

相当注意深く見ないと何が変わったのか全然分かりませんね…。第1コーナーを曲がったあととか最終コーナーの緑色の建物とかはまだ分かりやすいでしょうか。遠くの色が薄い状態の建物が、今回追加した遠距離レンダリングです。

Leave a Reply