WebGLの描画メソッド・プリミティブについて。

0 件のコメント

WebGLって何だっけ?

ここ読んで下さい。

筆者もすごく参考になってますありがとうございます。

初めての方は、読んでって言われても..って感じだと思うので、
概要だけ掴んだ後は下記のサンプルを実際にコードを書きながら試してみるといいと思います。
「ポリゴンのレンダリング」http://wgld.org/d/webgl/w014.html
(WebGLで三角形を描画するだけでも数十行コードを書く必要があります。

今回の記事は、上記のポリゴンレンダリングでも使われている、描画メソッド[gl.drawArrays]などについて記載しています。
そして、その描画メソッドで指定されているプリミティブについて解説していきます。
(プリミティブとは、描画メソッドで使用する描画モードみたいなもの。詳細は下記で。

WebGLの描画メソッド

下記の種類があります。これらを実行することで、canvas上に描画されます。
大雑把に書いているので、「gl.drawArrays」と「gl.drawElements」は下記で補足します。

gl.drawArrays
⇒ 頂点情報を配列で正しい順番に格納し、その内容で描画するやつ。

gl.drawElements
⇒ 頂点情報と、頂点情報の何番目を使って描画するのかの情報を格納し、その内容で描画するやつ。
drawArraysとの違いは、頂点情報の順番を気にしないでいいこと。
頂点情報の何番目を使うかを指定するので、頂点情報が重複する場合はデータを省略できる。

gl.clear
⇒ gl.clearColorで指定した色で描画する。初期化用みたいな感じ。

gl.drawArrays

頂点情報を配列で正しい順番で格納し、その内容で描画するやつ。

使い方
gl.drawArraysメソッドを使用する前に、下記の手順を踏まないといけない。
1. gl.createBuffer()でVBO(頂点バッファ)を作成する
2. VBOをgl.bindBuffer()で、ターゲットのgl.ARRAY_BUFFERにバインドする
3. gl.bufferData()で、バッファに頂点データをセットする
4. gl.enableVertexAttribArray()で、汎用頂点属性配列を有効にする
5. gl.vertexAttribPointer()で、頂点シェーダに記述しているattributeをVBOのデータに接続する

引数について
gl.drawArrays(
    enum [レンダリングしたいプリミティブ], 
    int [頂点データの配列で最初に使用する要素のインデックス], 
    int [頂点の数])

enum [レンダリングしたいプリミティブ]
下記のどれかを指定します。(頂点をそれぞれ、右記で表現します。v0, v1, v2, v3...)

gl.LINES 
⇒ 線です。例えば、v0とv1, v2とv3, v4とv5を線で結んで描画されます。
(この場合は線3つできます。

gl.LINE_STRIP 
⇒ 線です。例えば、v0とv1とv2とv3とv4とv5を線で結んで描画されます。
(この場合は各頂点を結んで一筆書き。

gl.LINE_LOOP 
⇒ 線です。例えば、v0とv1とv2とv3とv4とv5を線で結んで描画されます。
(この場合は各頂点を結んで一筆書きですが、終点v5と始点v0も線で結びます。

gl.TRIANGLES 
⇒ 三角形です。例えば、v0とv1とv2, v3とv4とv5を線で結んで描画されます。
(この場合は頂点6つで三角形2つ描画されます。

gl.TRIANGLE_STRIP 
⇒ 三角形です。例えば、v0とv1とv2, v1とv2とv3, v2とv3とv4を線で結んで描画されます。
(この場合は頂点5つで三角形3つ描画されます。じぐざぐ。

gl.TRIANGLE_FAN 
⇒ 三角形です。例えば、v0とv1とv2, v0とv2とv3, v0とv3とv4を線で結んで描画されます。
(この場合は頂点5つで三角形3つ描画されます。扇型。

gl.POINTS 
⇒ 点です。指定した頂点を点で描画します。点の大きさは[gl_PointSize]で指定できます。

合わせて読みたい資料はこちらです。
とっても参考になります。図付きですし。

※ このように、描画する手段が色々あるので、最適な描画手段を選ぶ必要があります。
正方形を描画するにしても下記パターンがあり、
使用する頂点数が少なければ処理すべきデータ数が減り、メモリからGPUに転送するデータ量も減ります。
・gl.TRIANGLESで頂点を6つ指定するパターン
・gl.TRIANGLE_STRIPやgl.TRIANGLE_FANで頂点を4つ指定するパターンなど

・int [頂点データの配列で最初に使用する要素のインデックス]
頂点データの配列で最初に使用する要素のインデックスを指定する。

・int [頂点の数]
頂点の数を指定する。

gl.drawElements

頂点情報と、頂点情報の何番目を使って描画するのかの情報を格納し、その内容で描画するやつ。
drawArraysとの違いは、頂点情報の順番を気にしないでいいこと。
頂点情報の何番目を使うかを指定するので、頂点情報が重複する場合はデータを省略できる。

使い方
gl.drawElementsメソッドを使用する前に、
gl.drawArraysの手順に加えて、下記の手順を踏まないといけない。
1. gl.createBuffer()でIBO(インデックスバッファ)を作成する
2. IBOをgl.bindBuffer()で、ターゲットのgl.ELEMENT_ARRAY_BUFFERにバインドする
3. gl.bufferData()で、VBOを使用する順序を決定するインデックス配列をセットする

引数について
gl.drawElements(
    enum [レンダリングしたいプリミティブ], 
    int [インデックスバッファのインデックス数], 
    enum [インデックスバッファに格納されている要素の型], 
    int [頂点データの配列で最初に使用する要素のインデックス])

enum [レンダリングしたいプリミティブ]
gl.drawArraysと同様。

int [インデックスバッファのインデックス数]
インデックスバッファに何個のインデックスがあるかを指定する。

enum [インデックスバッファに格納されている要素の型]
gl.UNSIGNED_BYTE
gl.UNSIGNED_SHORT
このどちらかの型を指定する。

int [頂点データの配列で最初に使用する要素のインデックス]
インデックスバッファのインデックスの開始位置を指定する。

まとめ。

描画メソッド・プリミティブよって、描画する手段が異なります。
正方形を5個くらい描画する場合は
gl.drawElementsとgl.TRIANGLE_STRIPを使うと頂点データの数や使用するデータ用量も一番小さくなります。

ただ、データ容量を小さくするのも大事ですが、
描画するものによって、最適なデータの持ち方を選ぶことも大事らしいです。

今後も何かWebGL関連の記事を書きたいです。

以上。


0 件のコメント :

コメントを投稿