Flash Stage3D対応のAway3D – 被写界深度表現

Flash Player 11のStage3D (FlashでGPUを利用することのできる技術)に対応した3Dライブラリ「Away3D」の紹介です。今回は定番の被写界深度表現を試してみました。

Three.js 版 (2023/05/14追記しました)

Away3D 4.1.4 GOLD 版 (2013/09/23追記しました)

  • Demo (要 Flash Player 11.7)
  • Source (ZIPファイル / Flash Pro CC または Flash Builder で利用できます)

Away3D 4.0.0 alpha 版

  • Demo (要 Flash Player 11.1)
  • Source (ASファイル)

前回紹介したとおりAway3Dには「DepthOfFieldBlur3D」というフィルター機能が備わっています。ただ、それは癖があり使いにくいので、このデモでは自前の処理にて実装しています。被写界深度表現の作り方については本ブログで既に紹介したことがありますが(下記リンク参照)、改めてAway3Dでの実装方法を紹介します。

ビットマップキャッシュの作成

ブラーフィルター(ぼかし)はリアルタイムに実行すると処理負荷が大きくなるので、予めぼかしを適用したビットマップを作成しておきます。次のスプライトシートは例ですが、ぼかしの強弱をつけた複数枚の画像を連番で用意するということが想像できればOKです。

ActionScriptでは、次のようなfor文を使って、配列にキャッシュ画像を保持しておくと便利でしょう。

for (var i:int = 0; i < ブラーの回数; i++)
{
var blurFilter:BlurFilter = new BlurFilter(i, i, 4);
var bmd:BitmapData = new BitmapData(128, 128, true, 0xFF000000);
bmd.draw(orijinal);
bmd.applyFilter(bmd, bmd.rect, new Point(), blurFilter);
// save
blurs[i] = bmd;
}

ビルボードの作成

ビルボードというのは、大雑把に言うと3D表現で常に正面を向いたオブジェクトのことを指します。ビルボードにしてしまうと、3D上の角度は表現できなくなりますが、そのかわりに3D描画や計算の負荷を抑えることができるので、大量にオブジェクトを表示したい場合には有効な手法です。

Away3Dでは、「Sprite3D」クラスがその機能にあたるので、これをインスタンス化して3D空間(scene)に追加しておきます。

var ball:Sprite3D = new Sprite3D(マテリアル, 横幅, 高さ);
scene.addChild(ball);

カメラとオブジェクトの距離の計算

被写界深度を計算するうえで、カメラと個々のオブジェクトとの距離の計算が必要になります。Away3DではObject3D.positionプロパティーにてローカル座標を、Object3D.scenePositionでワールド座標を取得できます。座標はFlash標準のflash.geom.Vector3D型なので、次のメソッドを呼び出せば、3D空間内の2点間の距離を計算できます。

var distance:Number = Vector3D.distance(camera.position, p.scenePosition);

ぼかしの適用

上記で求めた距離を使って、予めプリキャッシュしたビットマップのどれを割り当てるか計算します。とりあえず私は次のような計算をしましたが、計算によって配列の加減、上限を超えないように数値を丸めています。
var distance:Number = Math.abs(Vector3D.distance(camera.position, p.position) - FOCUS_POSITION);
var blurVal:int = Math.floor((distance / FOCUS_RANGE) * BLUR_DEPTH);
blurVal = Math.max(0, Math.min(BLUR_DEPTH - 1, blurVal));

そしてオブジェクトのmaterialプロパティーに新しいマテリアルを割り当てます。Away3D 4.0ではマテリアルの動的な差し替えはマテリアルオブジェクトの参照を差し替える形になります。

var p = particles[i];
var material = materials[blurVal]
p.material = material;

投稿者 : 池田 泰延

BookMark

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

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

Comment/Trackback %件

  • ステキング より:

    遂にFlashで動的で本格的なモーショングラフィックスが出来る時代がきましたな