機械学習基礎理論独習

誤りがあればご指摘いただけると幸いです。数式が整うまで少し時間かかります。リンクフリーです。

勉強ログです。リンクフリーです
目次へ戻る

WebGL2メモ

はじめに

本記事にはWebGL2に関する備忘録です。
WebGL2の習得に有用なサイトについても記載します。
私が後から参照できればよいので、わかりにくいかもしれません。

有用なサイト

・「床井研究室」でググってください。床井先生はCGの神様です。
wgld.org はい、これブックマークしてください。
webgl fundamental
コンピュータグラフィックス特論Ⅱ (大学院講義) 九州工業大学の授業のようです。私は影の箇所を参考にしました。
ゲームグラフィックス特論 A / B 床井先生の授業です。
ICS MEDIA - WebGLに関するハイレベルな記事があります。まだほとんど読んでません。がメモ!

シェーダの切り替え

頂点シェーダとフラグメントシェーダをまとめて切り替える方法です。
まず、gl.createProgram(); gl.attachShader(); gl.linkProgram(); シェーダに関する初期化を行います。

後は、そのシェーダを使うときに gl.useProgram(); を呼べばシェーダを切り替えることができます。

この方法はまとめて2つのシェーダを切り替える方法です。
頂点シェーダとフラグメントシェーダのどちらか一方を切り替える場合は、gl.dettachShader(); を呼ぶんだと思います。

デフォルトのフレームバッファのカラーバッファにクリアせずに随時書き込む方法

デフォルトのフレームバッファのカラーバッファは gl.clear() メソッドを呼ばずに gl.drawArrays() を呼ぶとカラーバッファがクリアされてしまいます。
(少なくとも見た目上はクリアされています。)
それを回避するために、canvas.getContext('webgl2', { preserveDrawingBuffer: true }); のように呼べばよいです。

バッファデータの動的切り替え

gl.bufferData() 後に配列の中身を変更した場合、再度gl.bufferData() を呼ぶのではなく、gl.bufferSubData() を呼ぶべき。
なお、gl.bufferData() の第三引数にはgl.DYNAMIC_DRAWを指定してやります。
wgld.orgのVBOを逐次更新しながら描画するの記事を参考にしました。

texImage2Dについて

mdnで調べると、以下の構文が書いてありました。

// WebGL1
texImage2D(target, level, internalformat, width, height, border, format, type, pixels)
texImage2D(target, level, internalformat, format, type, pixels)


// WebGL2
texImage2D(target, level, internalformat, width, height, border, format, type, offset)
texImage2D(target, level, internalformat, width, height, border, format, type, source)
texImage2D(target, level, internalformat, width, height, border, format, type, srcData, srcOffset)

下から2番目の呼び出し方をすればよいと思います。
width,heightには、画像であれば、そのまま画像のサイズを指定すればOKです。

gl.viewport() はよばなくても大丈夫

gl.viewport() はよばなくても動く。canvasの一部に書く時のみ必要となるのかな?

テクスチャの座標は左上隅を原点と考えてよい

よって、左回りは(0,0) -> (0,1) -> (1,1) -> (1,0) である。

canvasをテクスチャにしたときの更新方法

canvasの描画内容を更新した後、以下のようにバインドしなおす必要がある。

gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, canvas.width, canvas.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
gl.bindTexture(gl.TEXTURE_2D, null);   

テクスチャのバインドの仕方

安全な方法を書きます。

gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture0);
gl.uniform1i(uniLocation[1], 0);

gl.activeTexture()の後にgl.bindTexture()を呼ぶ必要があります。
gl.uniform1i(uniLocation[1], 0);の呼ぶ場所はどこでも構わないようです。
gl.activeTexture(gl.TEXTUREn);とgl.uniform1i(uniLocation[1], n); のnは数値であり、一致している必要があります。
nはいくつまで使えるのか気になりますが、私の場合は使っても0,1,2ぐらいなので調べてもいません。

IBO(インデックスバッファオブジェクト)の型を指定する方法

drawElementsで描画するときにIBOを使いますが、この時、配列の大きさによって型を変えた方が良いでしょう。
配列の大きさが65536(2の16乗)以下の場合、以下のような2バイトに対応するプログラムを書くべきです。

// Bind Data
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexes), gl.STATIC_DRAW);

// Draw elements
gl.drawElements(gl.TRIANGLES, indexes.length, gl.UNSIGNED_SHORT, 0);

配列の大きさが65536(2の16乗)より大きいの場合、以下のような4バイトに対応するプログラムを書くべきです。

// Bind data
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(indexes), gl.STATIC_DRAW);

// Draw elements
gl.drawElements(gl.TRIANGLES, indexes.length, gl.UNSIGNED_INT, 0);

ANGLEについて

ANGLEとは、ANGLE(Almost Native Graphics Layer Engine / アングル)というオープンソースのライブラリです。
WindowsChromeWebGLが動作するとき、
[ユーザーが記述したGLSL] -> [ANGLEが変換したGLSL] -> [ANGLEが変換したHLSL] -> [グラフィックスAPIDirect3D)]
といった具合に変換されます。
このことを「ANGLEのレイヤー上でWebGLが動作している。」というそうです。(ここでいうレイヤーというのは、ライブラリ上でぐらいの意味かな)
WebGL - WEBGL_debug_shadersで変換済みのシェーダーコードを確認するを参考にしました。

フレームバッファのコピー

WebGL 2.0 で追加されたblitFramebuffer()メソッドはフレームバッファー同士のコピーを行うAPIです。
詳細はこちらをご覧ください

BlenderからSTLファイルを出力するときの設定

何もしなくいてよい。Blender起動時のままの設定でよい。一応設定内容を貼り付けておく。

目次へ戻る