arusu0629のブログ

UnityエンジニアからiOSエンジニアへ

WebGLについて⑥

【前回】
arusu0629.hatenablog.com

※この章は少し長い内容となっております...mm

シェーダの記述と基礎

WebGLではプログラマブルシェーダの一種であるシェーダ言語が実装されている。それがGLSL(OpenGL Shading Language)である

GLSLを使って2種類のシェーダ、頂点シェーダとフラグメントシェーダを記述することが出来る。原則的に先に頂点シェーダが呼ばれます

頂点シェーダは、頂点に関する情報のすべてを渡すことが出来る
例えば、頂点の位置情報や、頂点が持つ法線、テクスチャ座標、頂点の色など、頂点に関する全てをシェーダに渡すことが可能

次にフラグメントシェーダは画面にどんな色を出力すればよいのかを決めることが出来る
画面上のピクセルそれぞれに対して、最終的に出力される色を操作してくれる

【ミニまとめ】
頂点シェーダは頂点に関する情報を、フラグメントシェーダは画面上の色の情報をそれぞれ処理するもの

■ものすごく単純な頂点シェーダの記述例
attribute vec3 position;

void main(void) {
    // 組み込み変数gl_Positionに頂点データを渡す
    gl_Position = position
}

attributeという修飾子を付けて宣言された変数(上記の場合はposition)が頂点の情報をシェーダ側で受け取る変数になる。つまりWebGLのプログラム側でpositionという名前をつけ、あらかじめデータを仕込んでおきシェーダに渡す


頂点シェーダは頂点に関する処理をするため、座標変換も頂点シェーダの仕事の1つです
どこまでを頂点シェーダに任せるかは自由ですが、WebGLのプログラム側でモデル・ビュー・プロジェクションのそれぞれの行列を生成して掛け合わせておき、最終的に出来上がった座標変換行列を頂点シェーダに渡すのが一般的

■座標変換行列をシェーダに渡す記述例
attribute vec3 position;
uniform mat4 mvpMatrix;

void main(void) {
    gl_Position = mvpMatrix * position;
}

uniform修飾子全ての頂点に対して一律に処理される情報を渡すことが可能になる
ここで出てきているmvpMatrixはモデル・ビュー・プロジェクションそれぞれの変換行列をかけ合わせた座標変換行列。その変換行列をWebGL側からGLSLに渡してあげる

attribute, uniformの2つの修飾子に加えて、varying修飾子があります
このvarying修飾子の使いみちは頂点シェーダとフラグメントシェーダの橋渡しです

例えば頂点シェーダが持つ頂点の色情報をフラグメントシェーダで使用したい場合などに使われます。(以下例)

頂点シェーダ
attribute vec4 position;
attribute vec4 color;
uniform mat4 mvpMatrix;
varying vec4 vColor

void main(void) {
    vColor = color;
    gl_Position = mvpMatrix * position;
}


続いてvarying修飾子付きの変数vColorを受け取るフラグメントシェーダ

フラグメントシェーダ
varying vec4 vColor

void main(void) {
    // フラグメントシェーダの組み込み変数gl_FragColorに色情報を入力する
    gl_FragColor = vColor;
}


このように頂点シェーダが持つ頂点の色情報をフラグメントシェーダに渡す際にvarying修飾子付きの変数を用いる。頂点シェーダで必須だったgl_Positionへのデータの代入と似たような形で、フラグメントシェーダにおいてはgl_FragColorにデータを入力する

【まとめ】

  • 頂点シェーダとフラグメントシェーダはGLSLを使って記述でき、基本的に双方がセットの形で使用する
  • シェーダ内部では必ずmain関数を用意してシェーダの行う処理を記述する
  • WebGL側から頂点の位置情報や色情報、座標変換行列などをシェーダに渡す際にattribute, uniformなどの特別な修飾子付きの変数を用意する必要がある
  • そして頂点シェーダからフラグメントシェーダにデータを渡す際にはvarying修飾子付きの変数を用意することで値を渡すことが出来る
  • 頂点シェーダは組み込み変数であるgl_Positionへのデータ代入が必須であり、またフラグメントシェーダはgl_FragColorに出力する色のデータを基本的に代入する必要がある


【続き】 arusu0629.hatenablog.com