PV3D演出サンプルNo.09:Spiral Particles

最近ブログで 3D 系のデモを投稿していなかったので、8ヶ月ぶりに。軌跡にそって、キラキラなパーティクルが3D空間に放出されるという Flash デモを作ってみました。

このデモは、ActionScript 3.0 の 3D エンジン「Papervision3D」とパーティクルエンジン「Stardust」を組み合わせて作ったデモです。どちらもオープンソースのライブラリで、MITライセンスなので無料で利用することができます。両方のライブラリとも当ブログで解説記事を数回にわたり投稿していますので、使い方を知りたい方は次の記事を参考くださいませ。

新しいテクニックみたいなことは特にないのですが、今回のデモで工夫したポイントを 2 点ほど紹介します。以下、Flashの技術的な解説です。

描画処理が高速なPapervision3DのPixelsクラス

最近のActionScriptテクニックに詳しい方にはよく知られていると思いますが、FlashではBitmapDataに直接ピクセルを書き込むのが最も高速な描画方法の一つです。

Papervision3Dでは3D空間の座標をBitmapDataのピクセルとして扱うためのクラス「Pixels」が用意されています。パーティクルというのは個数が必要になり描画・計算のコストが非常に高くなりがちですので、処理負荷の低いPixelsクラスを利用して大量のパーティクルを生成しているのが一つ目のポイントです。

ちなみに、Papervision3Dのライブラリを直接修正してPixelsクラスの処理速度を向上させるテクニックもあります。詳しくはPV3D演出サ ンプルNo.07:クリスマスメッセージの後半を参考に。

Stardustのレンダラーにカスタムレンダラーを使用

パーティクルの生成に便利なのが、パーティクルエンジンの「Stardust」。2つ目の工夫したポイントとしては、Stardustのカスタムレンダラーを作ったことです。

数百ぐらいのパーティクルであればStardustにビルドインされているクラスで十分ですが、それはParticleクラスを使用するため、数千レベルのパーティクルになるとハイスペックなマシンでもFPSが落ち込みます。

そこで描画負荷の低いPixelsクラスをStardustで処理する方向で考えてみました。PixelsクラスをStardustで処理するクラスはビルドインで用意されていないのですが、自前でカスタムレンダラーを作ることで実現することができます。作り方をまとめると次のようになります。

  1. StardustライブラリのRendererクラスを継承したクラスを作成
  2. particlesAddedメソッドをオーバーライドし、パーティクル追加の処理を定義
  3. particlesRemovedメソッドをオーバーライドし、パーティクル削除の処理を定義
  4. renderメソッドをオーバーライドして、パーティクルのレンダリング方法を定義

具体的にソースコードで示すと次のようになります。

import idv.cjcat.stardust.common.renderers.Renderer;
// Rendererクラスを継承
class MyRenderer extends Renderer {
  override protected function particlesAdded(
    emitter:Emitter,
    particles:ParticleCollection):void {
      // パーティクル追加の処理を作成
  }

  override protected function particlesRemoved(
    emitter:Emitter,
    particles:ParticleCollection):void {
      // パーティクル削除の処理を作成
  }

  override protected function render(
    emitter:Emitter,
    particles:ParticleCollection,
    time:Number):void {
    // パーティクルのレンダリング方法を定義
  }
}

なおRendererクラスのカスタマイズについては、wonderflに投稿されていたpaqさんの「Pixel3D with a brilliant radiance」を参考にしました。

※Stardust 1.1とStardust 1.2ではRendererのカスタマイズ方法が違います。本記事で解説しているのは最新のStardust 1.2での方法です。
※以前「パーティクル表現のためのAS3ライブラリStardust」のデモで使ったのは、Stardustビルドインのクラスです。

以上、久々の3Dデモの技術解説でした。
それでは、Stardustを使って楽しいパーティクルライフを!

追記:

まだ調整中ですが、違うバリエーションを作ってみました。パーティクルにBitmapDataのPixelではなく、Photoshopで作った雲画像を利用しています。

  • デモ (要 Flash Player 10.1 以上)

その他のPapervision3Dの演出サンプル

投稿者 : 池田 泰延

BookMark

ブックマークはこちらからどうぞ。

このエントリーをはてなブックマークに追加

Comment/Trackback %件

  • lowlydog より:

    Yasu様
    わたくしは台湾からの留学生ですが、最近Pervision3Dに惹かれて、YASU様の大作ーー
    「Flash3Dコンテンツ制作のためのPapervision3D入門」も買って勉強していますが、
    DAEに関して上手く行けなかった。
    私はMAYA2009からIKをBAKEしてOPENCOLLDAを利用し、この書き出ししたファイルをPV3Dに読み込んでアニメションをつくろうと思いました。
    だが、全然動けなかった。
    MAYAのOPENCOLLDAの時に書き出しが上手くいかなかったか、またはPV3DのSCRIPTが間違えたかどちらか分かりません。

    以下私のCODEです。
    //—————
    package {
    //必要のCLASSを読み込み。
    import flash.display.*;
    import flash.events.*;
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.objects.parsers.DAE;
    import org.papervision3d.materials.*;
    import org.papervision3d.events.*;
    import org.papervision3d.view.BasicView;
    //DAEのアニメションをやってくれるCLASS
    import org.papervision3d.core.animation.clip.AnimationClip3D;

    public class LoadModel extends Sprite {
    private var view:BasicView;
    //DAEを使う
    private var dae:DAE;
    //———————————-
    //AnimationClip3Dを使って些細なCILPに
    private var m_runClip:AnimationClip3D;

    //———————————-

    public function LoadModel() {
    init3DEngine();
    init3DObject();
    }
    private function init3DEngine():void {
    view=new BasicView(0,0,true,true,”Target”);
    view.camera.y=200;
    this.addChild(view);
    this.addEventListener(Event.ENTER_FRAME, onEventRender3D);
    }
    private function init3DObject():void {
    //DAEを利用。
    dae=new DAE(true,”dae”,true);

    //dae.load(“dae/miniBottle.dae”);
    //MYYAで作ったCOLLDAファイルを読み込む
    dae.load(“dae/nobones_ani.dae”);

          //大きさを微調整。
    dae.scale=100;
    //0から5秒までRUNというアニメションを宣告する。
    m_runClip=new AnimationClip3D(“run”,0.0,5);
    trace(m_runClip);

    trace(“問題を出る所の前”);

    //DAEに入れ
    dae.animation.addClip(m_runClip);
    trace(“WHY?!”);

          //プレーする。
    dae.play( “run” , false );

    view.scene.addChild(dae);
    }
    private function onEventRender3D(e:Event):void {
    //自動的にグルグル回す。
    dae.rotationY+=2;
    view.singleRender();
    }
    }
    }

    //—————————
    OPENCOLLDAの書き出しの設定とAnimationClip3D CLASSの使い方を教えて頂けませんか?

    お願いいたします。