【WebGL】GLSLの曲者varyingとuniformとは?その挙動の説明と使い方について
WebGL(GLSL)において、データを受け渡しする方法には3つあります。
- attribute
- varying
- uniform
目次から読む
varyingとは?
varyingとは、頂点シェーダからフラグメントシェーダへの値の受け渡しをするデータのことです。 JavaScriptから頂点シェーダへは、attributeが渡されますが、頂点シェーダからフラグメントシェーダへは、このvaryingが渡されます。 attributeとは?と不明な場合は、上の頂点シェーダのリンクを確認してみてください。 varyは英語で「変化する」を意味する単語です。 特徴としては、ユーザーで定義が可能で、 頂点間のフラグメントは線形補間された値が渡る点です。varyingのメリット
スムーズなグラデーションができる
このvaryingのおかげで、頂点間のフラグメントは線形補間されるため、 フラグメントシェーダでの色がスムーズになり、グラデーションも綺麗に表現することができます。 WebGLを使ったカラフルなグラデーションのサンプルデモはこちらで確認できます。光の反射を計算できる
頂点の法線をフラグメントに渡すことで、光の反射を計算できます。 物体の明るさを光を考慮して決められるということです。物体に画像や動画を貼り付けられる
varyingのuv座標を使用することで、物体に画像や動画を貼り付けて表現することができます。varyingを実装段階で覚えておきたいこと
頂点シェーダからフラグメントシェーダへは、このvaryingが渡されます。 つまり、頂点の位置はそれぞれ決定された後にvaryingが渡されるということです。 頂点シェーダでたとえば以下のコードを指定します。attribute vec3 position; //positionはそれぞれの頂点で異なる値を保持
varying vec3 vertexPosition; //フラグメントに渡すvertexPositionを宣言
vertexPosition = position; //頂点ごとに代入
positionはそれぞれの頂点で異なる値を保持します。
フラグメントに渡すvertexPositionを宣言します。
そして、頂点ごとにvertexPositionをpositionに代入します。
フラグメントシェーダでは以下のようなコードになります。
varying vec3 vertexPosition;
こうすることでvertexPositionに値が渡ってくるのですが、このときの値は、各フラグメントで異なります。
各フラグメントに、線形補間された値が渡ってきます。
uniformとは
uniformとは、頂点シェーダとフラグメントシェーダに一様な(uniformな)値を渡すものです。 同じデータといってもいいかもしれません。 varyingと同じく、ユーザーで定義が可能です。 異なる点として、varyingのように線形補間などはなく、全部の頂点と全部のフラグメントで一様な値を渡します。 用途としては、経過時間を使ったアニメーションだったり、 クリックされたときに状態変化させるアニメーションのことに使います。uniformの使い方
uniformの使い方はほぼvaryingと同じで、以下のように定義して、javaScriptなどからWebGLに値を渡すことができます。// 頂点シェーダ
uniform float u1;
void main() {
position += u1;
gl_Position = ...
}
// フラグメントシェーダ
uniform float u1;
void main() {
gl_FragColor = ...
}