Shader Cubicle

TwitterGitHub
Tweet

GLSLの基礎的な書き方を確認する

  • 頂点シェーダー
  • フラグメントシェーダー

ここまで適当にGLSLを記述してきたが、ここで記述のルールを見直してみる。

void main () {
  gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);
}
void main () {
  gl_FragColor = vec4(1.0, 0.0, 0.0, 0.0);
}

Shaderを描くための準備」でハローワールドとして上記のGLSLを書いた。この記述をもとに話を進める。

まず、最初のルールとして頂点シェーダー・フラグメントシェーダーともにmain関数の中に処理を記述する必要がある。

void main {
  //この中に処理を記述
  //...
}

その次に頂点シェーダーではGLSLの組み込み変数であるgl_Positionに値を渡す。というより頂点シェーダーの役割が、このgl_Positionに値を渡すことと認識していてもとりあえずは問題なさそう。

void main {
  // ...いろいろな処理
  gl_Position = position;
}

一方、フラグメントシェーダーの役割はGLSLの組み込み変数であるgl_FragColorに値を渡すことである(と認識していてとりあえずは問題なさそう)。

void main {
  // ...いろいろな処理
  gl_Position = color;
}

gl_Positiongl_FragColorvec4型、つまり4次元の浮動小数点ベクトルである。JavaScriptとは異なりGLSLは静的型付け言語なので、今扱っているデータの型が何なのかは常に意識する必要がある(JavaScriptでも型付けしないだけで意識しなくていいわけではない)。

ここで「WebGLProgram – three.js docs」を確認する。「前回の記事」でも軽く触れたが、Three.jsではビルドインでいくつかの変数が用意されている。ここまでShaderMaterialを使用してきたので、あまり意識してこなかったが、ビルドインで用意されている変数の前にuniformattributeといった修飾子がついているのがわかる(RawShaderMaterialではこの辺りの変数を自分で宣言する必要がある)。

attributeは頂点情報を受け取る変数を定義する修飾子であり、たとえばpositionはそれにあたる。頂点ごとに頂点情報を渡すので、attributeで宣言された変数は頂点ごとに異なる値を受け取ることができる。対して、uniformで宣言された変数はすべての頂点(フラグメントシェーダーならすべてのピクセル)で共通の値を受け取ることができる。modelMatrixviewMatrixprojectionMatrixなどの変換行列はすべての頂点で同様の行列なので、uniformで宣言されている。

頂点シェーダーからフラグメントシェーダーに値を渡す

さて、ここでvarying修飾子についても触れておく。varying修飾子は頂点シェーダーからフラグメントシェーダーに値を渡す際に使用できる修飾子である。百聞は一見にしかずということで、一旦実装してみる。

vertexShader
fragmentShader

上記で何をやっているかというと、まず頂点シェーダーにおいて、varying修飾子を使ってvColor変数を宣言する。その後vColorにvec4型の値を格納する(今回は青色)。ちなみにvColorの先頭のvはvaryingのvであり、uniformで宣言した時は先頭にuをつけることが慣習としてあるらしい。

// varyingで宣言
varying vec4 vColor;

void main () {
  // 青色を設定
  vColor = vec4(0.0, 0.0, 1.0, 1.0);
  //...
}

次に、フラグメントシェーダーでも同様にvColorの変数をvaryingで定義する。こうすることで頂点シェーダーからフラグメントシェーダーに値を渡すことができる。

// varyingで宣言、頂点シェーダーから値が渡ってくる
varying vec4 vColor;

void main () {
  // vColor = vec4(0.0, 0.0, 1.0, 1.0) のはず
  gl_FragColor = vec4(vColor);
}

試しに頂点シェーダーでvColorの値をいろいろ変えてみると、オブジェクトの色が変わることが確認できる。

以上でここまでに記述してきたGLSLの基本的なルールの確認ができた。

参考

前の記事へ次の記事へ