Papervision3D演出サンプルNo.03:フォトプリント

写真が3D空間をタイル状に集まって一枚の画像に仕上がるサンプルを作ってみました。ポイントは写真をタイル状のビットマップデータとしてキャプチャすることと、perlinNoiseを利用した放射状ブラー(ライトバースト)です。サンプルは以下から。

タイル状のパーティクル平面の作成

一枚の画像をタイル状に分割するのに、2重ループのなかで画像をずらしながらキャプチャしていきます。というのも、BitmapData.drawは原点からの横・縦しか指定できないので、キャプチャする画像は原点に移動させる必要があります。

// imgSpriteは画像を配置しただけのSpriteインスタンス
// folderはimgSpriteのラッパー
// 最終的にBitmapDataは配列bmpDataArrに保存

// パーティクルを分割して保存するループ
for (i = 0; i < MAX_CELL_W; i++ )
{
	for (j = 0; j < MAX_CELL_H; j++ )
	{
		imgSprite.x = - imgSprite.width / MAX_CELL_W * i;
		imgSprite.y = - imgSprite.height / MAX_CELL_H * j;

		var bmpData:BitmapData = new BitmapData(
			imgSprite.width / MAX_CELL_W,
			imgSprite.height/ MAX_CELL_H,
			false,
			0xFFFF0000
		);

		bmpData.draw(folder);
		bmpDataArr.push(bmpData);
	}
}

配列に保存したBitmapDataはBitmapMaterialで3Dテクスチャとして復元します。

// 保存されたパーティクル配列から3DのPlaneオブジェクトを作成(一部抜粋)
for (i = 0; i < MAX_CELL_W; i++ )
{
	for (j = MAX_CELL_H; j > 0 ; j-- )
	{
		// テクスチャは上記で作成したBitmapData配列を利用
		var material:BitmapMaterial =
			new BitmapMaterial(BitmapData(bmpDataArr.shift()), false);

		// Planeの作成
		var plane:Plane = new Plane(
			material,
			imgSprite.width / MAX_CELL_W,
			imgSprite.height / MAX_CELL_H,
			1, 1
		);
	}
}

ライトバーストの作成

フラクタルなランダムノイズといえばBitmapData.perlinNoise。ただグラデーションマスクをかけたかったので、タイムライン状でcacheAsBitmapを適用した上でマスクを設定しています。参考記事は以下。

モーションはゴリゴリとハードコーディング

今回はコードが煩雑になってきたのでFlash IDEを使って、適度にコードを短くしました。といってもカメラの動きなどトゥイーン関連はすべてTweenerで一個一個指定。3Dの演出を作るのはAfter Effetsのようにタイムラインで作った方が効率いいですが、トライ&エラーで調整。

ブログ内の関連記事

投稿者 : 池田 泰延

BookMark

いかがでしたでしょうか、ブックマークはこちらからどうぞ。

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

Comment/Trackback 7件

  • neil より:

    I am come from Taiwan. I like your blog 🙂 .

  • Yasu より:

    Thank you (^^)

  • flex入門 » Blog Archive » Papervision3D関連リンク より:

    […] http://clockmaker.jp/blog/2008/09/papervision3d_photo_particle/ […]

  • iku より:

    はじめまして^^
    これは1枚の画像で終わっていますが、見せたい画像が10枚ほどあった場合、どのようにMain.asファイルを書き足せばいいのでしょうか。
    できれば綺麗に次の画像に移行したいと思っているのですがやり方がわからなくて困ってます。

  • Yasu より:

    ikuさん、はじめまして。
    どのような演出やレイアウトで複数枚の画像を見せるかにより回答が変わってきます。もし1枚表示した後に別の写真を同じ位置で表示する演出の場合は、1枚目の表示演出に使用したインスタンスを破棄して、2枚目の写真も同様に画像の分割〜3Dパーティクルの演出を実行すれば良いと思います。

  • iku より:

    何度もすいません。
    一枚目の画像を破棄した後、
    21行目の
    ”static private const MAX_CELL_W:uint = 20;”
    から下をコピーしたソースを貼り付ければいいのでしょうか。

  • Yasu より:

    どこに貼り付けるにもよりますが、そのまま貼り付けるだけだと当然うまく動かないと思います。ロジックは理解していただくのは当たり前として、その上でカスタマイズください。

    そこまで理解すれば別の画像に差し替える機構を組み込むのはそう難しくないはずです。ヒントとすれば、BitmapDataのキャプチャする対象が別の写真になればいいだけですので。