レンダリングのための下準備
準備しなければならないもの
前回は 3D 描画のための基礎知識をおさらいしました。Z 座標の扱いを決める座標系の話や、座標変換の種類について解説しました。今回は、実際に WebGL で描画を行なうために準備しなければならないものについてお話します。
まず最初に言いますが、ここでは HTML や javascript に関する基本的な事柄については解説しません。もし、意味のわからない単語や言い回しが出てきた場合には各自調べてください。最低限の知識は有しているという前提で話をしますので、その点はご理解ください。
HTML の準備
さて、以前のテキスト(WebGL を始める前に canvas を知る)でも書いたように、WebGL は canvas を描画領域として利用します。当然、WebGL を使うウェブページでは HTML 内に canvas タグを含めておく必要があります。
また、その canvas には id を付加しておき、javascript から getElementById などで容易に参照できるようにしておいたほうがベターです。いったん canvas への参照が得られれば、そこから先は全て javascript 上で操作することが可能です。
本当に必要最低限の HTML のテンプレートとしては、以下のような感じになるでしょうか。
<html>
<head>
<title>WebGL TEST</title>
<script src="script.js" type="text/javascript"></script>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
</html>
上記のうち、script.js は自前で準備する各種処理を記述した javascript ファイルです。canvas の大きさは HTML 側で指定しておくこともできますし、当たり前ですが javascript のほうで動的に指定することも可能です。
また、HTML 内に全てのスクリプトを含めることも当然できます。個人的には、javascript は別ファイルで用意して参照するほうがスマートだと思ってしまうのですが、絶対に外部参照にしなければならないということではありませんのであしからず。
シェーダについて知る
WebGL には、いわゆる固定機能パイプラインというものが存在しません。そもそも、固定機能パイプラインとはなんぞや? という人もいると思いますので、話が少し逸れますが簡単に説明します。
固定機能パイプラインというのは、3D でレンダリングを行なう一連の処理の流れのことです。※ものすごくざっくりとした説明ですが雰囲気で察してください
固定機能パイプラインのなかでは、前回のテキストで出てきたような、モデル・ビュー・プロジェクションの座標変換をやってくれます。細かいことはわからなくても、とりあえず固定機能パイプラインのなかにこれらの座標変換の情報をぶっ込むだけで、勝手に計算をやってくれるわけです。
固定機能パイプラインが存在することによって、プログラムを記述すること自体は随分楽になります。なぜなら、座標変換の部分をまるまる固定機能パイプラインに任せることができるからですね。しかしこれには弊害もあって、逆に、自由度は低くなります。固定機能パイプラインがやってくれることは基本的なことだけですから、なにか特別な処理を記述したくても、なかなか融通は利かないというわけです。
さて、話を戻しましょう。
前述のとおり、WebGL には固定機能パイプラインは存在しません。つまり、座標変換は全て自前でやる必要があります。そして、この座標変換を記述するための仕組みこそがシェーダです。シェーダーという具合に最後を伸ばして発音する場合もあります。※というか英語表記は shader なので多分伸ばすほうが正しい
このようなプログラマが自前で記述できる仕組みのことをプログラマブルシェーダと呼んだりします。そしてシェーダには、ポリゴンの頂点情報を扱う頂点シェーダ(またはバーテックスシェーダ)と、描画される際のピクセルの情報を扱うフラグメントシェーダ(またはピクセルシェーダ)の二つの種類があります。WebGL では、固定機能パイプラインが存在しないため、この頂点シェーダとフラグメントシェーダの二つのシェーダを用意しなくてはなりません。
シェーダを記述する方法
頂点シェーダにしてもフラグメントシェーダにしても、いったいどこに、どのような形で準備しておけばいいのでしょうか。
実は、シェーダの実装方法にはいくつかやりかたが考えられます。というのも、シェーダはプログラムのなかでコンパイルされ利用されます。そしてそのシェーダのソースは単なる文字列でしかありません。ですから、なにかしらの方法で、シェーダのソースをプログラムに渡すことさえできればそれでいいのです。
一番簡単な方法は、HTML のなかにシェーダを記述したソースを埋め込んでしまう方法です。この方法を使う場合には、HTML の script タグを使います。簡単な例で示すと、以下のようになります。
<script id="vshader" type="x-shader/x-vertex">
※頂点シェーダのソース
</script>
<script id="fshader" type="x-shader/x-fragment">
※フラグメントシェーダのソース
</script>
canvas の場合と同様、javascript から参照できるようにそれぞれの script タグには id を付加しておきます。そして、type 属性を使って script タグの中身が javascript と誤認されないようにしています。
type 属性を指定している理由
type 属性の中身にある[ x-shader/x-vertex ]や[ x-shader/x-fragment ]といった記述は、いわゆる HTML で定義されている正式な書式ではありません。
ただ、一般的なブラウザは理解できない属性値が出てきた場合にはそれを無視するので、このように記述しておくことによって javascript として認識されないようにすることができるわけです。ブラウザ側から見れば無意味な文字列でしかありませんが、プログラムからその中身を参照して利用できるので問題はないというわけですね。
一方、script タグを利用しない方法もあります。
要するに、シェーダのソースは単なる文字列でしかないので、javascript の内部で文字列として記述しておきそれを利用する方法がそれです。この場合には、外部参照する javascript ファイル内でシェーダのソースを記述しておくなどすることで、HTML 自体を極力シンプルに仕上げることができます。まぁ、それ以上のメリットは特にないわけですが。
まとめ
WebGL による 3D レンダリングを行なうためには、今回解説したような下準備が必要です。
最低限必要となるのが、ウェブページの骨格である HTML と canvas タグ、そして WebGL の処理を記述した javascript と、頂点シェーダ・フラグメントシェーダのソースです。
そのほかにも、たとえば描画する 3D モデルのモデルデータや、画像ファイルなどが必要になる場合もありますが、それは WebGL でどこまでやりたいのかによって変わってくるでしょう。必要最低限のことだけを行うのであれば、HTML ファイル一本でもなんとかなります。javascript やシェーダのソースは、HTML 内に含めてしまうことも可能だからです。
基本的に、当サイトでは javascript は別ファイルとして参照するスタイルで解説していく予定です。また、シェーダの記述場所についても、必ずしも HTML 内で記述するとは限りません。そこはケースバイケースということで。
次回は、3D 描画の肝である行列について触れる予定です。