頂点シェーダーとフラグメントシェーダー
- 頂点シェーダー
- フラグメントシェーダー
前回の記事「シェーダーを描くための準備」で2種類のシェーダーを記述した。つまり頂点シェーダーとフラグメントシェーダーである。
頂点シェーダーとフラグメントシェーダーの詳細については次のMDNの記事を参照するとして、一応本記事でもざっくりと説明を書いておく。
頂点シェーダーはその名の通り、頂点に関する情報を扱うシェーダーであり gl_Position
というGLSLの組み込み変数に値を格納する。頂点シェーダーでは頂点に関する様々な情報を扱うことができるが、必要不可欠な情報として頂点の位置情報がある。頂点シェーダーは各頂点に対し、1回ずつ実行される。
フラグメントシェーダーはピクセルの色情報を扱うシェーダーであり、gl_FragColor
というこちらもGLSLの組み込み変数に値を格納する。描画対象にあるピクセルのRGBA(赤、緑、青、不透明度)を定義し、各ピクセルに対し、1回ずつ実行される。
頂点シェーダーを書き換えてみる
各々の役割がわかったところで、まずは頂点シェーダーを書き換えてみたい。「WebGLProgram ーThree.js」によると、頂点の位置は次のように計算できるらしい。
void main () {
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);
}
WebGLでは3次元の情報を(最終的にモニター映し出すために)2次元の情報に座標変換する必要がある。ありがたいことにThree.jsのShaderMaterial
では座標変換のために必要となる下記の変換行列をビルドインで用意してくれている。
projectionMatrix
: モデル変換。物体の位置を定義する。viewMatrix
: ビュー変換。カメラの位置や向きを定義する。modelMatrix
: プロジェクション変換。カメラがどの領域を映し出すかを定義する。
position
はオブジェクトの頂点座標であり、上述の座標変換された値が gl_Position
に格納されるわけである(ちなみにposition
もビルドインで用意されている)。
変換行列についてざっくり認識したところで、以下のように頂点シェーダーを書き換えてみる。
アーチ上に歪んだオブジェクトが確認できる(わかりやすくワイヤーフレーム状態にした)。次の操作を行っている。
書き換えているのはposition
の頂点座標と、モデル変換をしたmodelPosition
の値となる。まずposition
の頂点座標はX軸に沿って、Y座標をcos
で歪めている。
void main () {
vec3 myPosition = position;
myPosition.y += cos(myPosition.x); // オブジェクトのY座標をconで歪める
// ...
}
modelMatrix
はモデル変換行列であり、物体の位置を定義するものであった。つまり次の記述はオブジェクトの位置をZ軸に-1、Y軸に-1しているものである。
void main () {
//...
vec4 modelPosition = modelMatrix * vec4(myPosition, 1.0);
modelPosition.z += -1.0; // オブジェクトの位置をZ軸方向に-1
modelPosition.y += -1.0; // オブジェクトの位置をY軸方向に-1
//...
}
したがって上記の操作は、オブジェクトの頂点座標と位置に変更を加えたものとなる。
フラグメントシェーダーを書き換えてみる
次にフラグメントシェーダーの書き換えをしてみる。
こちらに関してはあまり説明することがないが、フラグメントシェーダーではgl_FragColor
にRGBAの色情報を格納するのであった。
void main () {
// (赤、緑、青、不透明度) = (1.0, 0.0, 0.0, 1.0);
vec4 rgba = vec4(1.0, 0.0, 0.0, 1.0);
gl_FragColor = vec4(rgba);
}
上記のコードではvec4 rgba = vec4(1.0, 0.0, 0.0, 1.0)
となっており、つまり赤色の情報を定義したことになる。試しにrgba
を任意の値にすることで、色が変更されるのを確認できる。