calendar

S M T W T F S
     12
3456789
10111213141516
17181920212223
24252627282930
<< November 2019 >>

categories

archives

PV3Dでのパフォーマンス向上テクニック

0
    今回はPV3Dでのパフォーマンス向上テクニックについてです。

    最近のFlashの3D技術は単なるデモだけでなく、ゲームなどのコンテンツを作成しているブログをよく見かけますが、どの方も同じように「パフォーマンスが思うようにでない」という悩みにぶち当たるようです。例えば自分が作っているようなゲームなんかだと、自機、敵機、自弾、敵弾、爆発エフェクト、背景、音楽、効果音、スコア管理なんかを同時並行で処理していく為、どうしても処理が重くなってしまいます。コンテンツ作りの7割近くがパフォーマンス向上に対しての労力を割いているのではないかと思えるほどです。

    なので、とりあえず今まで自分が試行錯誤してきた中で気付いた点で特に効果が大きいものを書いてみます。
    まあ内容的に当たり前なものやインチキっぽいものまでありますが、苦労した中で気付いたものですので、積極的に情報共有していくべきかと思い書くことにします。


    。械追漸茲良蕾戮StatsViewを表示させて確認する。
    PV3Dには、3D描画に関する情報を表示させるStatsViewというクラスがあります。使い方は簡単で、以下のようにオブジェクト化してaddChildするだけです。

    import org.papervision3d.view.stats.StatsView;
    -------------------------
    var sv:StatsView = new StatsView(renderer);
    addChild(sv);


    この様にFPSや、描画されている▲ポリゴン数、メモリ使用量などが表示されます。特にメモリ使用量は、実行環境プレビュー、swfダブルクリック実行、HTML上からの表示で変りますが、HTMLからの表示で、できれば5MB前後、少なくとも10MB以下で抑えられるように最終調整していきます。またメモリ使用量は増えていって一気に下がる、を繰り返しますが、多分ガベージコレクタの動きを反映していると思われます。

    描画総ポリゴン数は1000以下にする
    というか、500位が理想です。StatsViewのCTr数で確認できます。ポリゴン数が少ないほどパフォーマンスが良くなる、といえば当たり前ですが、特に顕著に如実に結果に表れますので、試行錯誤して如何にポリゴン数を減らすか、という地道な作業の積み重ねが大事です。もちろん、キャラクタ自体はローポリ化するに越したことはないですが、例えば遠くの背景なんかはbitmap化して一枚のPlaneに張り付けたりします。特に球体はポリゴン数が多くなりがちなので、Planeに球体の絵のbitmap貼り付けが効果的です。

    あともっともポリゴン数を消費しがちなのが「床」です。これはtanjoさんがレースゲーム作成記で行われている、1枚のPlaneにbitmap.drawして書き換えていくという手法が現時点では最も効果的だと思います。


    Tweenerはメインのクラスのものを共有して使う
    クラス(ファイル)が複数になってくると、各クラスの頭にTweenerクラスをimportして使いがちですが、パフォーマンス上これはよくありません。メインとなるクラスにのみTweenerをインポートし、それをそれぞれのクラスで使いまわします。記述方法として正しいか分かりませんが自分は以下のような感じでやっています。


    ■メインとなるクラスは、thisを引数として子クラスを生成する。

    import caurina.transitions.Tweener; //メインとなるクラスのみTweenerをインポートする

    public var w = Tweener; //子クラスなどでも共有して使うTweener
    public var c:hogeClass;

    //子クラスを生成
    c = new hogeClass(this);


    ■子クラスはコンストラクタで親クラスを変数に割り当てる
    private var p;
    public function hogeClass(prmP):void //コンストラクタ
    {
    p = prmP;
    }

    ■子クラスからTweenerを使う場合
    p.w.addTween(〜)


    ・・・うーん、分かりずらくてスイマセンw

    3Dモデルよりも、できるだけParticleやLines3Dを使う
    例えばレーザビームは細長い立方体ポリゴンモデルを使うよりも、Lines3Dで線を一本描画して終わり、とします。空気中のチリやホコリや雪なんかはParticlesFieldを使います。これらは描画的にはシンプルな線・点としての表現になってしまいますが、事パフォーマンスに対してのメリットは大きいですので、全体のバランスを考えながら効果的に使っていきます。

    DisplayObject3Dの入れ子はできるだけ1重にする。
    sceneに直接3Dモデルなどを置くことができますが、Tweenerで動かしたときにスムーズに動かない場合があるようですので、3DモデルはできればDisplayObject3DにaddChildさせて使います。

    var do3d:DisplayObject3D; //コンテナとなるDisplayObject3D
    do3d = new DisplayObject3D;
    scene.addChild(do3d); //sceneにaddChild

    var c = new hogeChara(); //表示させる3Dオブジェクト
    do3d.addChild(c); //直接sceneにaddChildさせず、DisplayObj3ct3DにaddChildする。

    //キャラを移動させる場合は、cではなくdo3dを動かす。

    また、例えば人間の肩・肘の関係を表現する場合などはDisplayObject3Dをネストさせていく事で表現することができますがネストしすぎると、パフォーマンスへの影響が大きくなるようです。できるだけDisplayObject3Dのネストは1回のみ、多くても2回までと意識するのがいいかと思います。

    Γ械張ブジェクト生成・addChildは一番最初にすべて行っておく
    3Dオブジェクト生成・addChildは、一瞬ですがパフォーマンスを犠牲にします。最悪画面が一瞬止まります。例えば雑魚キャラを次々に表示させる場合、表示の度に雑魚キャラ生成・addChildするのではなく、ゲーム初期化時に最大数を生成しておき、あとはvisibleを切り替えたりしてその生成されたオブジェクトを使いまわします。(ただし、モノによってはいちいちremoveChildした方がパフォーマンス上がる場合もあるようなので、一応覚えときましょう)

    当たり判定などは毎フレームやらなくていいものもある
    自分はゲームは今のところすべて30FPSで作っていますが、自機の当たり判定などは、毎フレームやらなくても問題ありません。Timerイベントを使って
    ENTER_FRAMEの負荷を下げるのも効果があります。どの判定がどの程度端折れるかは試行錯誤しながら調整していきます。


    なんか全体的に分かり辛い内容になってますね、スイマセン。
    まだいろいろあるんですが疲れたのでとりあえず一旦ここまでとしますw
    では。

    コメント
    コメントする








       
    この記事のトラックバックURL
    トラックバック