iOSでの対応も進んできて、WebGLが盛り上がってきているかなと感じてるので、プログラミングをしてみました。
といっても、wgld.orgという、すごいサイトがあったので、あまりできることもなく、
そちらで取り上げられていない、トーンマッピングをとりあえず実装してみました。
ソースコードは、GitHubに上げています。
いろいろとまとめているので、あまり見やすくはありません。
個別の技術については、wgld.orgさんを読むのが大変に勉強になります。
プログラムは下記から実行してください。
WebGLを始めるのはかなり簡単です。html のサイトに、スクリプトとキャンバスをヘッダとボディに記述しておきます。
<head><script src="main.js" type="text/javascript"></script></head> <body><canvas id="canvas"></canvas></canvas>
次に、JavaScript内で、キャンバスを取得して、取得したオブジェクトから、WebGLのコンテキストを取得します。
var c = document.getElementById('canvas'); var gl = c.getContext('webgl') || c.getContext('experimental-webgl');
後は、取得したコンテキストを使って、たとえば下記の様な描画関数を呼び出します。
gl.drawElements(gl.TRIANGLES, index_count, gl.UNSIGNED_SHORT, 0);
ゲームのメインループは、最初に呼び出されるスクリプトのonload関数内で、一定時間後に処理を行うsetTimeoutを使ったループ処理を書けば、その部分を繰り返し続けます。
(function(){ メインループの処理 setTimeout(arguments.callee, 1000 / 60); })();
後は、wgld.org さんの記事を読んでいけば、非常に短期間に習得できると思います。
なお、ローカルのファイルで画像等を読み込むには、Chromeの場合、--allow-file-access-from-filesオプションを付けて起動する必要があります。
開発をする際は、このオプションのショートカットを用意しておくのが便利でしょう。
トーンマッピングとは、おおざっぱにいえば、HDRの線形空間で計算した結果をLDRで見れるようにする画像変換です。
最近のレンダリングは、浮動小数点などの高輝度に対応したバッファにレンダリングして、レンダリング結果の最大輝度などから適切な明るさに調整して画面に表示します。
(あと、デバイスの特性を修正するガンマ補正も行われます)。
今回は、下記の様なシェーダで、固定定数を使って浮動小数点数バッファにレンダリングした結果を0-1の間に輝度を納めて、ガンマ補正の後に出力をします。
こちらは、HTMLファイル内に記述しています。
<script id="Tonemapt_fs" type="x-shader/x-fragment"> precision mediump float; uniform sampler2D texture; varying vec2 vTexCoord; void main(void){ vec4 decale = texture2D(texture, vTexCoord); decale.xyz = 1.0 - exp( -0.5 * decale.xyz); // gamma coreect gl_FragColor = vec4( pow(decale.x, 1.0/2.2), pow(decale.y, 1.0/2.2), pow(decale.z, 1.0/2.2), decale.w); } </script>
同時にテクスチャを読み込む際も、このガンマ補正を打ち消す変換をかけています。
そして、残念なことに手にいれたばかりのiPhone6で実行したら、浮動小数点数バッファへのレンダリングには対応していなかったので、iPhoneで実行する際には、8ビットのフォーマットでレンダリングするようにしています…
簡単で、特別な開発環境もいらないし、かなり複雑なことまでできるので、 CGの入門には、これからはWebGLが最適だと感じました。