こんにちは、ICS池田です。先日開催したAway3D勉強会の発表のフォローアップ記事となります。
写真をRGB3原色に分解して3次元で表示するHTML5 + WebGLのデモを作ってみました。ステージをドラッグすると写真が赤・青・緑の3原色に分解されて表示されます。ライブラリはJSライブラリの「Away3D TypeScript」を使っています。
このデモを通して紹介したいのは次の3つです。
- 色分解のロジック
- Flashライクで高機能なHTML5版BitmapDataクラスの紹介
- Flash Stage3Dにフォールバック可能なAway3D TypeScriptのレンダラー
以下で、それぞれについて詳しく紹介していきます。
1. 色分解のロジック
Web上の多くの画像は赤・青・緑の光の3原色(8bit深度)を使って構成されています。これを確認するにはPhotoshopが便利で、[チャンネル]パネルを使えば赤・青・緑それぞれのピクセル情報を確認することができます。
今回のデモにおいては写真をRGB(赤・緑・青)のレイヤーに分解し、それぞれ描画モード「スクリーン」(もしくはピクセルのカラー情報を加算するもの)に設定して黒背景に重ねています。そうすることで元の画像が復元されます。参考までにPhotoshopで同じことを再現しようとすると次の状態となります。
2. Flashライクで高機能なHTML5版BitmapDataクラスの紹介
HTML5 Canvas (Context2D)を利用すれば、画像解析/加工することができます。ただし、HTML5 Canvas (Context2D)は低レベルのAPIしか提供されていないために、実現したい機能がある場合は自分でJavaScriptのコードを記述する必要があります。
今回利用したJSライブラリ「Away3D TypeScript」には画像を3原色+透明度に分解するBitmapData#copyChannel()というメソッドがあります。これを使えば少ないコードで分解した色情報を得ることができます。
BitmapData#copyChannel()というメソッドの使い方
BitmapData.copyChannel(ソースのビットマップデータ, 元素材の範囲矩形, 貼付け先の座標, 元素材のRGBチャンネルを指定, 貼付け先のRGBチャンネルを指定)
使用例
// 変数 var w:number = image.width; var h:number = image.height; var p:Point = new Point(0, 0); var rect = new Rectangle(0, 0, w, h); // ImageエレメントをBitmapDataに転写 var bmd = new BitmapData(w, h); bmd.draw(image); // 保存先を準備 var r = new BitmapData(w, h, true, 0xFF000000); var g = new BitmapData(w, h, true, 0xFF000000); var b = new BitmapData(w, h, true, 0xFF000000); // 各チェンネルをコピー b.copyChannel(bmd, rect, p, BitmapDataChannel.BLUE, BitmapDataChannel.BLUE); r.copyChannel(bmd, rect, p, BitmapDataChannel.RED, BitmapDataChannel.RED); g.copyChannel(bmd, rect, p, BitmapDataChannel.GREEN, BitmapDataChannel.GREEN); this._result = [r, g, b];
色分解については次のデモを試してみてください。読み込んでいるのはオリジナルの写真ですが、JavaScriptによって赤・緑・青の3画像(Canvasエレメント)に分解されています。
Flashの経験者なら気づいたかもしれませんが、BitmapData クラスはFlashのAPIで存在します(Flash 8の頃からあります)。BitmapData クラスはHTML5やWebGLには元々存在しないのですが、Away3D TypeScriptにはFlash互換のAPIがいくつか整備されています。Flash経験者が学びやすい設計になっているのもAway3Dの魅力の一つです。
3D空間への展開
3原色に画像を分解したらAway3D TypeScriptを使ってWebGLの中で3D空間に配置。3D上の3平面は描画モードを加算(BlendMode.ADD)にしています。注意した点としては遠近感がつくと3平面がずれてしまうので、Away3DのOrthographicProjectionクラスを利用して、平行投影をするようにしました。
Away3D TypeScriptでの平行投影
// 平行投影を利用 var projection = new OrthographicProjection(); projection.far = 60000; projection.projectionHeight = 1500; this.camera.projection = projection;
3. Flash Stage3Dにフォールバック可能なAway3D TypeScriptのレンダラー
Away3D TypeScriptの凄い機能として、WebGLが未搭載のブラウザではFlash Playerにフォールバックします。次のキャプチャ画像はWebGLがデフォルトで無効であるMac Safari 7でのデモを動かしたものです。
※次期Safari 8ではWebGLがデフォルトで有効になるらしいですが、執筆時点の最新のMac Safari 7では開発者オプションを使わない限りWebGLは無効となっています。
スクリプトの処理自体はJSで行われていて、描画部分だけFlash側で再現しているようです。これを実現するにはWebGLのGLSLとFlash Stage3DのAGALのコードの変換であったり、JS側からSWF側へのテクスチャの転送など、どれをとっても実現が難しいことばかりです。 Away3Dではそれが内部的に実現されていて正直驚くばかりです。
最後に
いかがでしたでしょうか? Away3D TypeScriptはFlashライクなAPIが用意されているだけでも使いやすくて嬉しいのですが、Flashへのフォールバックのエンジンまで搭載されています。昨今、WebGL対応のブラウザが増えてきてはいるものの、実際のところ古いブラウザも数多く残っています。用途によってはフォールバックの機能は重宝するかもしれません。
今後もICS LABではAway3D TypeScriptのデモを作成して紹介していこうと思います。ぜひFacebook公式ページをフォローするなどして、ブログの更新をチェックくださいませ。
参考にしたサイト