WebGL開発者必見! Flash Stage3Dとの比較から見えてくるWebGLのあり方について
こんにちは、ICS池田です。
12月といえばアドベントカレンダー。今年はWebGLのアドベントカレンダーに私も表明しましたので、テーマ「Flash Stage3D との比較から見えてくる WebGL のあり方について」をテーマとして記事を書いてみます。長文ですが、Stage3DとWebGLのそれぞれの技術について特徴をまとめていますので最後までお付き合いくださいませ。
WebGLとStage3Dとは
Stage3DとはFlash(Flash PlayerやAdobe AIR)からOpenGL/DirectXを利用することのできる技術です。2011年にリリースされたFlash Player 11 / Adobe AIR 3に搭載され、多くの商用コンテンツで利用されてきました。
WebGLはプラグイン無しにブラウザの標準技術としてOpenGLを利用することのできる技術です。2014年になってIE11やiOS8 Safariで搭載されたことにより多くのブラウザで表示できるようになり注目を集めています。CSS3やCanvas Context2Dなどの他のWeb標準技術で3Dを実現できますが、WebGLを使えばより高度な3D表現や高速な2D表現の作成が可能になります。ともにGPUを利用する技術ですが、ほぼ同等の表現が実現できます。今回の記事ではそれぞれの技術の異なる点と両技術のメリット・デメリットを掘り下げていきます。
対応環境について (ブラウザ編)
両者の特徴的な相違点は再生できる実行環境の違いです。Stage3Dのほうがリリースされた時期が早かったことやブラウザのプラグインモデルを採用していることもあり、Stage3Dは新旧幅広いデスクトップブラウザで利用できます。例えばサポート終了した13年前のブラウザIE6でも動作しますし、旧式プラグインモデルNPAPIを排除することを宣言したGoogle Chromeに対しても新式のPPAPI版Flash Playerが標準搭載されています。ただしFlash Playerがスマートフォンのブラウザに搭載されていない(※一部を除く)のため、スマートフォンのブラウザではStage3Dを再生することができません。
対してWebGLは2014年現在使用できるブラウザが限られます。大きなシェアを持つ旧式のIE8〜10はWebGLに対応しておらず、商用案件では利用しにくいことがデメリットでしょう。スマートフォンではiOS 8 Safariで標準対応、Androidでは一部のOS・メーカー・ブラウザを除き再生できます。Androidでは一律に再生可能だと言い切れないことや、iOS 7以前はWebGLが再生できませんが、近い将来にWebGLがスマホブラウザで幅広く実行できる時代がやってくると予想できます。Can I Useによれば現時点で74.64%のGlobal Browser UageでWebGLが利用可能としています。
※追記:FirefoxやAndroid2.x系の標準ブラウザではFlash PlayerをインストールしてFlashコンテンツを再生することができます。しかし、Stage3DはスマートフォンのブラウザではAPIが未対応のため再生できません。
※追記:類似の技術Unityに関してはPPAPI版のUnity Web Playerが存在しないため従来のUnityコンテンツがGoogle Chromeで再生できなくなります。しかしUnity 5ではWebGLとして出力できるようになる予定で期待されています。
対応環境について (アプリ編)
Stage3Dのメリットとして、Flash(Adobe AIR)で作成すればスマートフォンのアプリケーションとしてデプロイすることが可能です。Adobe AIRはiOSとAndroidのそれぞれに同一のコードからアプリケーションとして出力でき(※OS依存の箇所は除く)、最近のスマートフォンではほぼOpenGL ES 2.0が搭載されているため、ほぼ確実にStage3Dを利用できます。スマホアプリ/タブレットアプリとして同一のコードからGPUをしたコンテンツを制作するには適した技術だと言えます。
WebGLはWeb Viewを介することでHTML5のアプリケーションとしてデプロイすることが可能です(例えばPhoneGapがWeb Viewを介する技術です)。しかしWebGLはその端末の標準ブラウザがWebGLに対応していることが条件のため、アプリとしてデプロイしたからと言って必ずしもWebGLが動作することは限りません。その点ではスマホブラウザと同様にWebGLが標準搭載されたデバイスのシェアが浸透するまで商用に利用しにくいと言えます。
Phone Gapを使えばHTMLをアプリ化することが可能だが、WebGLがどの環境でも確実に動作するかは別問題
シェーダー言語の違い
Stage3DとWebGLはともに頂点シェーダー(バーテックスシェーダー)と断片シェーダ―(フラグメントシェーダ―)の両方を使って3Dを実現します。しかしシェーダー言語が異なり、Stage3DではAGAL(エーギャル)を、WebGLではGLSL(ジーエルセスエル)を利用します。
Stage3Dでは幅広い環境で再生できるようにするための解決策として、ブラウザ/OSによってOpenGLかDirectXかどちらか最適な方を利用する仕組みとなってます。そのため、シェーダー言語は両方に変換可能なものを使う必要があり、AdobeはAGALという言語を用意してそれを実現しました。対してWebGLではOpenGLのみを利用するため、OpenGLのシェーダー言語であるGLSLをそのまま記述することができます。
両者を比較すると、GLSLでは関数が使えることが大きなメリットでしょう。AGALでは1回のドローコールで実行できる命令長が200まで、各シェーダーで使用できる変数がベクトル換算で8本ずつまでというような決して充分とは言えない上限があります。これに加えて関数を使用できないため少し複雑なことをしようとするとすぐにこれらの上限に達してしまいます。例えば、ライトを1つ実現するために命令を数十使うために使用できるライトの数に制約ができてしまい、3D空間にライトを数個しか配置できないというような不便な点出てきてしまいます。GLSLでは関数が使えるため命令数をコンパクトに抑えることができるので、AGALで不便に思うような制約があまりありません。
上記のような使用できるリソースの制限に関して言えば、一見すると使用できる数が多いためGLSLのほうに軍配が上がります。ただし、この数は実行環境に依存するため、「経験則から考えられるある程度の数」以上を使おうと思うと、実行時に使用できるリソース数のチェックと、条件に満たなかった場合の対策が必要になってきます。もちろんAGALも実行環境に依存する点はあるのですが、リソースに関しては再生できる環境であれば最低限が保証されているため、特に気にする必要がないというのはAGALのメリットと言えるでしょう。
※AGALの上限はAGAL2 (Stage3DのStandardプロファイル)で緩和されています。
フレームワークの違い
両者の技術も共にシェーダー言語を使って1からコンテンツを作るのは生産効率的に選択しがたいです。高レベルなAPIとして構築されたフレームワークを利用するほうが、機能実装が素早くコンテンツの作り込みに注力することができるからです。ではWebGLとStage3Dではどのようなフレームワークが存在するのでしょうか? 次に各種フレームワークをまとめてみました。
WebGLのフレームワーク
- Pixi.js (2D)
- EaselJS (2D)
- Three.js (3D)
- AwayJS (2D・3D)
Stage3Dのフレームワーク
- Away3D (3D)
- Alternativa3D (3D)
- Flare3D (3D)
- Minko (3D)
- Starling (2D)
- Feathers (2D)
GPUを利用するというイメージから3D表現を思い浮かべられますが、WebGLもStage3Dも3D表現のものだけではありません。Stage3DとWebGLはともに2Dと3Dのフレームワークが存在し、2Dでも3Dでも高速な描画処理が可能となります。3Dの表現、パフォーマンス、モデルデータの読み込み対応(読み込める形式の種類やパースの速度)、モデルデータ作成のワークフローなど様々な観点から検討する必要があります。WebGL界隈では「Three.js」一強の状態が続いていますが、採用にあたっては慎重に検討したほうがいいのではないかと思います。
[Flash Stage3D] フレームワークの選定では3Dモデリングソフトからのワークフローが充実しているか検討したい。Away3DではExporterのプラグインが用意されている。
2Dと3Dの組み合わせ
WebGLであれば、WebGLのビューポートであるcanvasタグよりも上位にDOMエレメントを配置しCSSで制御が可能なためHUDの構築が簡単です。これに関してはさくーしゃさんもHTML5 Rocksの記事「Case Study: Inside World Wide Maze」で「HTML5 + CSS3 のレイアウト機能は非常に強力で」とメリットとしてあげています。
対してStage3Dも同様にFlashのDisplayListを利用してHUDを作ることができます(Stage3Dの上位レイヤーにDisplayListを配置することで)。Adobe Flash Professional CCを使ってGUIのツールで直感的に作成できます。この設計は弊社も開発に関わっているスクエニレジェンドワールドで採用しています。
制御スクリプト
WebGLはブラウザ標準機能を使って実装するため、基本的にはJavaScriptで実装します。ご存知の通りJavaScript (現行のECMA Script 5も含む)はレガシーな言語であり、リッチなウェブサイト・コンテンツ・アプリケーションが求められる時代になったのに、言語機能がニーズに追いついていないのが現状です。JavaScriptを使ってWebGLコンテンツを作るのはデモレベルならいいですが、高度なコンテンツを作るには個人的にはJavaScriptを素のまま記述するのは向いているとは思えません。WebGLフレームワークのAPIが多岐に渡ることと3Dコンテンツでの大規模開発を見越して、WebGL開発には静的型付けの言語のTypeScriptやHaxeを利用することを提案したいです。弊社だとプロジェクトで数万・数十万行のコード量に達すること多々ありますが、このボリュームになると静的型付けの言語ではなければ生産性・保守性の高い水準を保つことができないと判断しています。
Flash Stage3DはActionScript 3.0を利用します(ActionScript 1.0/2.0でStage3Dを制御することはできません)。ActionScript 3.0はECMA Script 4をベースとしており、Javaのような言語となっています。開発環境として高機能なAdobe Flash Builderや無償のFlashDevelop等が充実しているため、大規模開発に向いているという利点があります。JavaScriptはインタプリタでActionScript 3.0はコンパイル済となるため、実行時のパフォーマンスは一般的にはActionScript 3.0のほうが高いと言われています。次の図板はHTML5にもFlashにも両方存在する物理演算ライブラリBox2Dを使って、ActionScriptとJavaScript等のパフォーマンスをグラフ化したものです(左側にあるほうが高速)。
ネイティブレベルの実行速度を実現する技術
話題がWebGLとStage3Dから離れますが、JavaScriptとActionScriptを更に高速に実行する手段が存在します。これらの技術はアプローチはそれぞれ異なりますが、基本的にはネイティブレベルのパフォーマンスを得るためにC/C++等で開発されたロジックをモジュール化し、JSやAS3で叩けるようにしています。高度な計算や計算量の多いロジック(例えば物理演算など)で使うことで、実行速度の遅いJS/AS3の弱点を補うことができます。
JS 側
ActionScript 3.0 側
asm.jsは変換後はJSのコードになるので幅広いブラウザで動作しますが、asm.jsの効果が得られるのがFirefoxのみです。PNaCLはネイティブモジュールとなりGoogle Chromeのみで動作します。CrossBridge(Flash)はSWFになり様々なブラウザで利用可能です。一部のブラウザに依存する技術(asm.js, PNaCL)と幅広いブラウザで利用できる技術(CrossBridge)という違いがあります。ただ実際のところ、これらの技術は実装難易度が高すぎるので、アピールコンテンツを除いては採用事例はほとんどありません。
デバッグ
Flash Stage3DではデバッグツールとしてAdobe Scoutが存在します。Adobe Scoutは非常に高性能・多機能でフレームレート・CPU負荷・メモリ量・GPUメモリ量・AGAL命令・ActionScriptの実行を計測することができます。
[Flash] Stage3Dに関しては命令毎に実行結果をプレビューする機能も備わっているため、AGALの命令が正しく実装できているかどうかを確認するのに役立つ
- 実行されているドローコール等の命令をチェックできるツール
Chrome 上で、Canvas API のダンプ、Draw call の可視化、スナップショットが取れる Canvas Profiles が超便利なのでご紹介 – latest log - シェーダーや頂点バッファ等の状態をチェックできるツール
Chrome extension, WebGL Inspectorが超便利 « イナヅマTVログ
制御スクリプトに関してもAdobe ScoutとFlash Builderのプロファイラを併用することでFlashだと非常に精度の高いチューニングが可能です。
JavaScriptだとChromeのデベロッパーツールでも残インスタンスの計測ができます。
[WebGL] ChromeだとJSの残インスタンスのチェックして、メモリリークチェックができる
まとめ
Stage3DとWebGLの違いをまとめてきましたが、コンテンツ制作においては類似の技術であるため、片方で習得したノウハウやテクニックはもう片方でも同様に応用できることが多々ありました。一例を紹介すると、私個人のブログではFlashで制作したものをWebGLに数点移植しています。WebGLとStage3Dの両者の技術を使えれば非常に幅広い環境へアウトプットできるはずです。
世論や流行だけで判断するのではなく、エンジニアとしてそれぞれの技術の特性を正しく理解し、最適な使い分けを心がけていきたいところです。ICSではWebGLとStage3Dの両者の技術のそれぞれの長所を活かして、今後も取り組んでいます。
最後に
難しい話が多くなってしまいましたが、WebGLアドベントカレンダーの今後も楽しみにしています。明日はtkihiraさんですね!よろしくお願いします!