はじめに
こんにちは。@kioku_systemkです。
ここ数日のWebGLアドベントカレンダーではGLSLでおもしろい絵をだすという紹介記事が多いですね。
GLSLを使えば別に3Dに限らずいろいろな模様などもGPUのパワーを利用して高速に表示することができますね。
メガデモについて
メガデモ(megademo)という言葉を聞いたことがあるでしょうか?
海外ではデモシーン(demoscene)という単語のほうが一般的です。
ヨーロッパを起源としたコンピュータを使った音と映像の作品を作成し、みんなに見せ合うというカルチャーです。
詳しくは、少し長いですが、以下の動画が参考になります。
(音声は英語ですが日本語字幕がついています)
Moleman 2 - Demoscene - The Art of the Algorithms (2012)
メガデモの作り方
音楽に合わせて、なんだか格好良さよさそうな作品があるのはわかったけど、
さてどうやってつくればよいのか?という疑問が浮かびます。
検索すると、WebGLで技術的な表示デモはみかけるのですが、
作品をつくるにあたって、どのようにWebGLを書けばよいのかが
書かれたものがあまり見つけられなかったので、今回の記事にしました。
最近のメガデモ
最近のメガデモではGLSLを利用したデモが多いです。
GLSLは手軽にGPUのパフォーマンスを利用できるだけでなく、
小さなサイズのデモを作る場合にも効果的なので、よく利用されます。
GLSLsandbox や ShaderToyには多くのデモシーナーが作品を投稿しています。
今までのメガデモは実行ファイル形式のものが主流でしたが、
最近はWebGL作品も増えてきました。
また、世界に向けて作品を発信するのに、圧縮ファイルを一度ダウンロードして
解凍し実行しないといけない実行ファイル形式の作品より、
WebブラウザですぐにみえるWebGLメガデモがこれから、
より増えていくのではないかと思います。
できるメガデモ
実は2年まえにメガデモアドベントカレンダーというので、
できるメガデモ製作(サイトアクセスが少し重いかもしれません)という記事を書きました。
前回はC++とOpenGL(GLSL)での実装でしたが、今回はそれのJavaScript+WebGL(GLSL)での実装を行いました。
デモ
まずはデモを見てみましょう。
そのまま移植したかったんのですが、iPhoneなどでの動作を
考えて、少しGLSLのループの値を調整しています。
解説
デモのメイン処理(demo.js)
このファイルがデモの中心となるファイルです。
WebGLとデモの初期化、メインループの処理、ウインドウ処理を記述しています。
WebGLに関する基本的な解説は@h_doxasさんのwgld.orgを参考にするのがオススメです。
demo.js:6行目付近
sceneTableというテーブルでシーン切り替えの定義をしています。
sceneClassというところで、どのシーンを順番に表示するか、
そのシーンの再生時間はどれくらいにするかをtimeに設定しています。
ここで再生する曲に合わせたシーン切り替えを行うことができます。
シーンの内容は後述のScene1-4.jsに記載してあります。
demo.js:29行目付近
ここで時間によるシーンの切り替え処理を行っています。
demo.js:45行目付近
ここで初期化処理をしています。WebGLの直での初期化ですが、Three.jsなどを
利用したい方はこのあたりで初期化しておきましょう。
demo.js:59行目付近
AudioPlayerでmusic.mp3を読み込んで再生しています。
ここでは曲の読み込みが完了してからメインループを実行するようにしています。
曲の読み込みが完了してからの再生でないと、曲とシーンの再生のタイミングがずれてしまうため注意が必要です。
demo.js:66行目付近
ウインドウいっぱいに広がるようにキャンバスの大きさを調整しています。
demo.js:75行目付近
最初にページを表示したときにSTARTのボタンを押したら
ボタンを消して、再生を開始するようにしています。
これはiOSなどでは音を再生するのにユーザー起因のイベントからしか再生することができない仕様になっているため、
ユーザがボタンを押したというイベントから音の再生(デモの初期化)を行うようにしています。
PC向けのブラウザにはこの制約は無いため、loadFunc内から直接init();を呼ぶことで、自動的にデモを再生することができます。
音楽再生(audioplayer.js)
audioplayer.js
音楽再生モジュールです。内部でWebAudioを利用し、再生中のWave波形とWaveスペクトルを取得できるようにしてたのですが、
今回のデモではiOS版での動作がうまくできなかったため、ダミー関数を仕込んでいます。
audioplayer.js:78行目付近
IEやiOSなどの互換性を考えて、今回はaudioタグによる再生を行っています。この方法だと様々なプラットフォームで利用できますが、スペクトルなどの値が取得できないため、音にシンクロしたデモが少々作りにくいです。
audioplayer.js:58行目付近
デモの基準タイムはAudioPlayerのgetTime()関数から取得します。音楽基準の時間を取得することで、曲とシーンがずれることがなくなります。またAudioContext利用時のcurrentTimeは通常のDate関数よりも高性能な時間が取得できるそうです。
Scene1-4.js
これがどんなシーンかを定義するクラスです。
- Scene1.js
- Scene2.js
- Scene3.js
-
Scene4.js
はそれぞれ
GLSLによるシーンを定義しています。
ここではGLSLでのシーンのみですが、Three.jsなどを利用しても
同様の処理になると思いますので Three.jsでデモを作ってみたいひとは改造してみてくださいね。
一番簡単なのはSceneE.jsです。
デモが終わったときに黒い画面が表示されるように黒でクリアしているシーンを表示しているだけです。
シェーダ表示用クラス
ShaderDrawer.js
GLSLシェーダのみのシーンを表示するための便利クラスです。
各Scene[X].jsから呼ばれています。
おまけ(Server.js)
node.jsでローカルにHTTPサーバーをたてて、iOSなどのデバイスでテストしやすい用にしました。
作品をつくって発表しよう
デモシーンでは、作品ができたら、デモパーティと呼ばれるオフ会のようなところに持っていき、発表します。発表された作品でどれが一番よかったかを参加者が投票して決めます。
日本ではTokyo Demo Festというデモパーティが毎年開催されています。
WebGLデモ、GLSLデモの作品も受け付けているので是非作品をだしてみてくださいね。
2014年度は7行のGLSLで作品をつくるという作品を募集しました。
7 Lines GLSL Graphics Compoに挑戦してみよう!
また、もちろんWebGLなら、作品を自分のWebサイトを通じて世界に配信できますね。
近年はiOS/AndroidなどもWebGLに対応しているため、
PCがなくても手軽にWebGLデモをいろんな人に見せられる環境が整ってきました。
何かの技術デモをつくって公開するときなどがあると思いますが、
せっかくなら曲もつけて、演出込みでデモをするほうがかっこ良く見えますよね。
読者のCoolなデモ作品が見えるのを楽しみにしています。