WebGL2は基本的には3DグラフィックスのためのAPIですが、2Dグラフィックスにも応用することができます。WebGL2を使って2Dグラフィックスを描画する方法を学んでみましょう。

WebGL2の基礎について

WebGL2は複雑なAPIを持っています。全てを説明していると非常に長くなります。WebGL2のAPIの使い方に関しては、本ブログの「WebGL2入門」の記事を読んでください。

2Dグラフィックスを描画する方法

WebGLは3DグラフィックスのためのAPIです。2Dグラフィックスを描画するには、ほんの少しだけ遠回りが必要になります。

2Dグラフィックスの描画は、三角形ふたつで四角形を作り、そこにテクスチャを貼ることで実現できます。

これだけです。以上!終わり!

描画の最適化

たったこれだけで終わるのも悪い気がするので、もうちょっと話を続けましょうか。

WebGL2はそのままでも高速に描画できる仕組みですが、いくつかの最適化手法を使うとこで、より効率的に実行できるようになります。

テクスチャアトラス(スプライトシート)

一般に、WebGLを扱うときは、テクスチャ1枚だけを貼って終わり、ということはありません。複数の絵柄を、様々な位置に描画したいはずです。しかしそれぞれの絵柄を別のテクスチャにしていると、描画コストもかさみますし、なによりWebGL2で扱えるテクスチャの上限は最低で32枚なので、すぐに上限に達してしまいます。

よって複数の絵柄を一枚のテクスチャに納めるテクスチャアトラス(またはスプライトシートとも言う)という手法がよく使われます。テクスチャアトラスを用いることで、描画コストを抑えることができ、テクスチャ枚数の節約にもなります。

テクスチャアトラスの例

描画の際には、テクスチャアトラスの一部だけを切り出して使うことになります。

TRIANGLE_STRIP

テクスチャを貼り付けるための四角形の描画方法も様々です。WebGL2にはQUAD(四角形)はありませんが、TRIANGLES(三角形)はありますし、TRIANGLESで三角形を2つくっつければ四角形が完成します。

もちろんTRIANGLESでも十分な速度は出ます。しかし一般的にはTRIANGLE_STRIPの方が描画が速いと言われています。TRIANGLE_STRIPは、1つの頂点と、前の描画に利用した2つの頂点の、3頂点を利用して三角形を描画するプリミティブです。

縮退三角形(縮退ポリゴン)

しかしTRIANGLE_STRIPには問題があります。前の2頂点を使うために、離れたところの三角形を描画できません。素直に実装すると、全部の四角形が繋がって描画されてしまいます。

そこで縮退三角形(縮退ポリゴン)というものを使うことで、四角形を切り離して描画することができます。縮退三角形は面積ゼロの三角形のことで、これは面積がないので画面に描画されません。つまり見えない糸のようなものです。

この縮退三角形で四角形を同士をつないでいくことで、TRIANGLE_STRIPの弱点である、「連続している三角形しか描画できない」を克服することができます。

例えば2つの四角形、「0-1-2-3」と「4-5-6-7」があった場合、インデックスバッファを「0-1-2-3-3-4-4-5-6-7」にすれば、「3-3-4」の部分で縮退三角形ができ、2つの四角形をつなぐことができます。

実際に組んでみる

ここまでの知識を活かして、実際に2Dグラフィックスを描画するプログラムを組んでみましょう!

デモ

試しに、以下のような簡単なグラフィックを描画するプログラムを組んでみましょう。

ここをクリックでデモを開きます

バーテックスシェーダ

まずはバーテックスシェーダから手をつけてみます。バーテックスシェーダでやることは、頂点座標とテクスチャ座標を受け取り、適切に処理するだけです。しかしこれだけでは少し面白みがないので、もうちょっと工夫しましょう。

WebGLは、そのままでは-1.0から1.0までの値を取る座標になります。

これはなかなか扱いにくいです。2Dグラフィックスで一般に使われる、0から始まり、横幅・縦幅の整数で終わるような座標で記述できるようにしてみましょう。これは平行移動と拡大縮小で実現できます。

平行移動と拡大縮小の行列は、プログラム側から転送することにします。

フラグメントシェーダ

フラグメントシェーダ側でやることは、特にありません。愚直にテクスチャを出力しましょう。

テクスチャの用意

描画を行うには、テクスチャが必要です。これはあらかじめこちらで用意しておきました。

クリックで画像ファイルを開く

クリックして画像ファイルを開き、保存してください。ファイル名は「atlas.png」です。

プログラム

プログラム側では特に難しいことは必要ありません。必要な情報を用意し、転送するだけです。

先述のとおり、四角形を描画し、そこにテクスチャを貼り付けます。TRIANGLE_STRIPで描画し、四角形同士は縮退三角形で繋ぎます。

詳しいことはコメントに書いてあります。よくわからない場合は「WebGL2入門」を読みましょう。

HTMLファイル

HTML側の書き方がわからない人はいないとは思いますが、一応HTMLファイルも置いておきます。

これで完成です!実際に動かして確かめてみましょう。