GLSLを使って、オレオレ畳み込み機能を作ってみよう
- フラグメントシェーダーの記述言語として、GLSLを学んでみる
- GLSLでの処理をハックして、テンソル計算をやってみる
- テンソル計算ができるようになったら、機械学習の推論処理を行う仕組みを作ってみる
ブラウザからGPUリソースにアクセスして、3D/2Dの描画(レンダリング処理)を行うためのJavaScript API。
レンダリングを行う対象としては、点・線・三角形 となっており、それらを組み合わせて描画したいモノの形を定義ができるようになっている。 つまり、複雑なポリゴンを描画したい場合は、三角形の組み合わせ方や配置法則の定義等をWebGLのAPIを介して定義してあげる必要がある。
そして、定義したポリゴンの頂点情報をもとに、頂点シェーダを用いた変形処理(後述)を行う。 また、フラグメントシェーダを用いた画面の色の決定(後述)を行う。 これら、頂点シェーダとフラグメントシェーダの処理は、自前で定義でき、それをWebGLのAPIを介して呼び出すことで任意の画像を描画できるようになっている。
グラフィックスカードの実行のためのコードと命令が含まれたアセットのこと。 そもそも、GPUは一般的に3Dのオブジェクトに対して、以下の2フェーズの処理を行なっている。 このフェーズ内で、シェーダーを用いている。 特に、頂点シェーダ・フラグメントシェーダ・ジオメトリシェーダは、ユーザ定義可能なシェーダとして、プログラマブルシェーダと呼ばれる。
-
頂点パイプライン
- 頂点シェーダー
- 頂点単位での陰影処理
- テッセレーション
- LOD(Level Of Details)処理として、頂点の分割計画/分割/意味付けを行う
- ジオメトリシェーダ
- 頂点の増減を動的に実施
- 頂点シェーダー
-
ラスタライズ
- 3Dのポリゴンをカメラを通して見た2D画面上にどう映るかを計画し、2D情報に切り取る
-
ピクセルパイプライン
- フラグメントシェーダ(ピクセルシェーダ)
- ピクセル単位の陰影処理
- テクスチャの適用
- レンダーバックエンド
- ステンシル処理等
- フラグメントシェーダ(ピクセルシェーダ)
上記処理の詳細は割愛するが、昔は全てハードウェアでカバーされ、機能のUpdateと共にハードウェアの買い替えが必要であった。 近年は、シェーダはユーザがプログラムで定義できるようになり、さまざまな3D/2D表現ができるようになった。
頂点シェーダ・フラグメントシェーダの記述が可能なC言語ベースの言語。 GLSLでは、上記2つのシェーダを合わせて「プログラム」とよぶ。
頂点情報(x, y, z座標を持つベクトル)1つ1つに処理を実行する機構
この時、頂点情報は、 クリップ空間と呼ばれる、描画ように切り出された領域を表す数字で表現される。 この数値は、キャンバスのサイズ関係なく、-1 ~ 1の間の値をとる。
つまり、「元となる頂点情報」に対応する「クリップ空間上の値」を、 何らかの計算をして求め、その値を特別な変数である「gl_Position」に書き込むこと。
// 入力として、4次元(x,y,z,w)の頂点情報を受け取る
attribute vec4 a_position;
// 全てのシェーダーは「main」の関数が必要
void main() {
// gl_Positionを得ることが頂点シェーダの目的
// ここでは、入力のベクトルをそのまま返しているだけ。
gl_Position = a_position;
}描画する2D画面の各ピクセル単位に、テクスチャ適用、陰影計算を行い、実際の色を出力するための処理を実行する機構 具体的には、ピクセル単位で色を計算して、その値を特別な変数である「gl_FragColor」に書き込むこと。
ピクセル単位の膨大な計算が必要ではあるが、GPUの力を使うことで並列・高速化を実現させる。
precision mediump float;
// 全てのシェーダーは「main」の関数が必要
void main(void){
// ターゲットとしているピクセルの位置を取得し、512.0(ディスプレイサイズ)で割ることで、0~1の間の値に縮尺を変える
float a = gl_FragCoord.x / 512.0;
// gl_FragColorを得ることがフラグメントシェーダの目的
// ここでは、左から右にかけて赤色のグラデーションが行われるように各ピクセル色が得られる
gl_FragColor = vec4(a, 0.0, a, 1.0);
}普通、GLSLではピクセル単位にテクスチャを適用し、光源や法線マップに従った陰影処理を行う。
中でも、テクスチャを適用する処理に着目する。 テクスチャ自体は、色情報(RGBa)を定義する2次元の配列データであるため、このデータをテンソル計算の入力と見立てる。 そして、テクスチャの乗算処理を行う行うことで、テンソル計算と同等の結果を得る。
当然、GPUによる並列・高速化の恩恵が得られるため、普通にJavaScriptで計算を実装するよりも高速になることが期待できる、という算段である。
Tensorflow.jsではどうやってWebGLを利用しているのか? → https://tfujiwar.hatenablog.com/entry/2018/05/21/120815
WebGLの基本 → https://webglfundamentals.org/webgl/lessons/ja/webgl-fundamentals.html

