出来る限りシンプルに WebGL の冗長な記述をスマートにするヘルパーライブラリ twgl.js
WebGL 熟練者が生み出した珠玉の一品
今回ご紹介するのは WebGL のヘルパーライブラリ twgl.js です。
作者の方は、three.js の開発に貢献したり、自分でも WebGL の実装を多数行ったりと、WebGL 界隈ではかなり活動されている方です。
今回ご紹介する twgl.js は、出来る限り少ない記述量で、スマートに WebGL の実装を行えるように作られています。three.js ほどの重厚さはなく、あくまでもスクラッチ記述の WebGL 実装を可能な範囲で簡素化できるというものです。
学習用にも、またサクッと WebGL の実装を行う上でも、非常に役に立ちそうなライブラリです。
コードを比較することで見えるものがある
この twgl.js が持つ思想は、個人的にはすごく共感できる部分が多いです。
スクラッチで WebGL を記述することは、たくさんの手続きの連続になりやすくとても冗長になります。twgl.js はこれをうまくラッピングして簡素化してくれる一方で、three.js のように素の WebGL の仕組みが完全に隠蔽されるわけではありません。
ある程度、スクラッチで WebGL の記述を行ったことがある人なら、その記述例を見るだけで作者の方の思いが読み取れるのではないでしょうか。
twgl.js の専用サイトや Github を見ると、どちらに書かれているものも同じ内容だとは思いますが Example と記述例のコードが掲載されています。
Example はそれほど難しい内容のものではなく、いずれも非常にシンプルです。
幾何学モデル描画の例を中心に、テクスチャを用いたものや環境マッピングを適用したものなどが掲載されています。
これは文字列を板ポリに貼り付けている Example を実行しているところ。
こちらはカレイドスコープを模した描画結果。
一見すると何らかのアルゴリズムによって模様を描いているように見えるかもしれませんが、これは一度フレームバッファに描いた描画結果を拾ってきているようですね。
画面をクリックすると、裏でどのような風景をレンダリングしていたのかが見れるようになっています。
冒頭でも書いたように、このライブラリは無駄を排することが大きなテーマになっています。これは、専用サイトや Github に掲載されている記述例を見るとよくわかります。
WebGL をスクラッチで記述したことがある人なら特に、思わず「あるある」と言いたくなるのではないでしょうか。
ここでは抜粋して掲載してみます。
WebGL の標準的な記述の場合
var u_lightWorldPosLoc = gl.getUniformLocation(program, "u_lightWorldPos");
var u_lightColorLoc = gl.getUniformLocation(program, "u_lightColor");
var u_ambientLoc = gl.getUniformLocation(program, "u_ambient");
var u_specularLoc = gl.getUniformLocation(program, "u_specular");
var u_shininessLoc = gl.getUniformLocation(program, "u_shininess");
var u_specularFactorLoc = gl.getUniformLocation(program, "u_specularFactor");
var u_diffuseLoc = gl.getUniformLocation(program, "u_diffuse");
var u_worldLoc = gl.getUniformLocation(program, "u_world");
var u_worldInverseTransposeLoc = gl.getUniformLocation(program, "u_worldInverseTranspose");
var u_worldViewProjectionLoc = gl.getUniformLocation(program, "u_worldViewProjection");
var u_viewInverseLoc = gl.getUniformLocation(program, "u_viewInverse");
var positionLoc = gl.getAttribLocation(program, "a_position");
var normalLoc = gl.getAttribLocation(program, "a_normal");
var texcoordLoc = gl.getAttribLocation(program, "a_texcoord");
これはシェーダ側に正しくデータを送信するために必要な手順のひとつです。パッと見た感じ、すごく無駄なことをいっぱいやっているように見えるのではないでしょうか。
WebGL はこういった冗長な手続きが必要になる記述が本当に多いのですが、一方、これと同じことを twgl.js を使って記述するとどうなるかというと……
twgl.js を利用した場合
var programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);
なんとたったの一行で済んでしまいます。
上記の変数programInfo
は javascript のオブジェクトになっていて、WebGL に関する情報をプロパティとして持っています。うまくオブジェクトでラップすることにより、情報へのアクセスルートをしっかり残しつつ、手順だけを簡素化しているのですね。
ここに記載したのはあくまでも一例ですが、twgl.js 全体にこのような「無駄に冗長な処理」を簡略化することで記述する手間を軽減するという精神が満ちています。
three.js レベルにまで WebGL を完全に隠蔽してしまうと、three.js の使い方を理解したからといって WebGL に関する知識はほとんど得られません。しかし twgl.js はスクラッチで WebGL を記述する上で便利な機能の集合体という感じで、無駄に隠蔽しすぎてしまうことはありません。WebGL の学習用として、非常に優れたライブラリだなと思います。
WebGL の仕組みを学習しながら、どう記述するのが効率的なのかを知ることができるでしょう。ぜひ参考にしてみてください。
リンク:
TWGL.js, a tiny WebGL helper library
greggman/twgl.js ※Github のページ