前回に引き続き、WebGLスクールの復習です。
前回
免責事項
3Dや数学の専門家ではないので、所々おかなしな記述があるかもしれません。
予め、ご承知おきください。
IBOについて
IBO(Index Buffer Object)は頂点インデックスを格納するオブジェクトです。
例えば↓の図のような正方形を描画したいとします。
※便宜上、三角形を離しているので正方形に見えないかもしれませんが、心の目で見てください...
描画したいのは正方形なので、本来4つの頂点で描画できるはずなのですが...
プリミティブ形状にgl.TRIANGLES
を指定すると三角形を2つ書いて正方形を描画することになるので頂点は6つになってしまいます。
結果として、2つの頂点が無駄に描画されることになってしまいます。
そんな時、IBOを利用すると頂点B・Cを再利用して頂点D・Eを省く
といった実装が可能になります。
var position = [
-0.5, 0.5, 0.0,
0.5, 0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0
];
// 色情報、左から順にRGBA
var color = [
1.0, 0.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
0.0, 0.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0
];
// 中略
// iboの作成
var indexes = [
0, 1, 2,
1, 2, 3
];
var ibo = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Int16Array(indexes), gl.STATIC_DRAW);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);
// 中略
gl.drawElements(gl.TRIANGLES, indexes.length, gl.UNSIGNED_SHORT, 0);
4つの頂点で正方形が描画されますね!
こういう単純な図形ではありがたみはないです。
ですが、複雑なモデルデータを描画する場合は地味に利いてくるテクニックだと思います。
余談
ちなみに、gl.TRIANGLE_STRIPを利用しても良い感じに正方形は書けます...が
頂点の利用順序に制限があるので、融通が利かないです。
var position = [
-0.5, 0.5, 0.0,
0.5, 0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0
];
// 色情報、左から順にRGBA
var color = [
1.0, 0.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
0.0, 0.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0
];
// 中略
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
深度テストについて
深度テストは簡単に説明すると、手前のモデルが奥にあるモデルを覆い隠すかをテストする機能です。
これを利用しないと、奥のモデルが手前のモデルから透けてしまい不自然な描画になってしまいます。
サンプルを見ると、イメージしやすいかも...です。
正8面体の裏面が描画されるタイミングで違和感を感じる...はず。
実際に深度テストを有効にするコードは下記のようになります。
gl.enable(gl.DEPTH_TEST);// 深度テストの有効化
gl.depthFunc(gl.LEQUAL); // 深度テストの比較関数を指定
実際に深度テストを利用したサンプルは下記となります。
深度テストに利用できる比較関数は下記ですが...
- gl.NEVER
- gl.LESS
- gl.EQUAL
- gl.LEQUAL
- gl.GREATER
- gl.NOTEQUAL
- gl.GEQUAL
- gl.ALWAYS
実質はgl.LEQUAL
の一択らしいです。
※なぜこの一択かは、不勉強なため分かりません...
最後に
今回の実装サンプルは下記にありますので良かったら見てください。
来週6/13がまた講義なので、勉強してきます!!