本稿は「Using Variable Qualifiers」ページを翻訳したものです。
変数修飾子を使用することで、変数の使用方法がさらに定義できます。変数修飾子は変数の型(floatやvec2など)の前に置きます、
変数修飾子:const または#define の使用
constは”constant”の略で、プログラムの実行中、決して変化しない変数です。作成したconstは上書きできません。p5と異なり、PIなどの定数はシェーダーコードにないので、PIを使用するにはコード内で定数を定義する必要があります。これには2つの方法があります。
const float PI = 3.14159265358979323846;
// または
#define PI 3.14159265358979323846;
#defineの使用は、const float 変数名 と比べ、変数でなく、シェーダーがコンパイルされPIの記述が指定された数値に置き換えられる前に実行されるスクリプトである点が異なります。#を使ったシンタックスは”プリプロセッサディレクティブ”と呼ばれます。メモリに保持される変数でないので、理論的には高速で効率的です。
変数修飾子:attributeの使用
attributeは頂点ごとのパラメータなので、頂点ファイル(.vert)でのみ使用されます。通常はp5シェイプの頂点データを受け取るために使用され、使用可能な形式に変換されてフラグメントシェーダに渡されます。
attributeは、シェーダーをシェイプにマッピングするときに、.vertコードですでに使っています。
// WEBGL/p5からの頂点データ
attribute vec3 aPosition;
変数修飾子:uniformの使用
uniformは定数変数ですが、constと異なり、フレームごとに一定の定数です。これは、draw()呼び出しごとに更新できるということを意味しています。uniformにはGPUのすべての並列スレッドからアクセスできます(パイプの例で紹介したモナ・リザを思い出してください)。uniform(一様)と呼ばれるのは、各スレッドが受け取る情報が同じであるからです。すべてのスレッドは結果として一様である必要があるので、1つ1つのスレッドは入力データの読み取りは可能ですが、変更はできません。
uniformについて知っておくべき重要なことは、情報をCPUからGPUにどうやって渡すか、言い換えると、p5からシェーダーコードに情報を渡す方法です。
p5からよく渡すuniformは時間や解像度、マウスの座標です。これらには、前に”u_”や”u”を付けた名前がプラクティスとして使用されます。以下は3つのuniformを送るp5コードの例です。
// 解像度(キャンバスの大きさ)
theShader.setUniform("u_resolution", [width, height]);
// 時間。ミリ秒値1000で割って秒に変換
theShader.setUniform("u_time", millis() / 1000.0);
// マウス座標。シェーダーが適切な方向を向くようにYをひっくり返す
theShader.setUniform("u_mouse", [mouseX, map(mouseY, 0, height, height, 0)]);
フラグメントシェーダ(.frag)では、uniformを受け取り、それぞれの型(vec2,floatなど)で定義します(変数名にはp5.Shader.setUniform()で指定した名前を使う)。
uniform vec2 u_resolution;
uniform float u_time;
uniform vec2 u_mouse;
リファレンスメモ
setUniform()
gl.uniform()関数のラッパー。シェーダーにuniform情報を保持するとき、その情報を使って、与えられたデータの型チェックを行い、適切な関数を呼び出すことができる。
シンタックス
setUniform(uniformName, data)
パラメータ
uniformName 文字列: シェーダープログラムでのuniformの名前
data オブジェクト|数値|ブール値|数値[]: そのuniformに関連付けるデータ、型は様々(単一の数値、配列、行列、テクスチャ/サンプラー参照)
変数修飾子:varyingの使用
varyingはフラグメントごと(ピクセルごと)のパラメータで、ピクセルごとに異なり(vary)ます(uniformはすべてのピクセルで同じ)。varyingは多くの場合、WEBGL/p5から得たテクスチャ座標を、頂点シェーダーからフラグメントシェーダに送るために使用します。変数名をつけるときには、前に”v”や”v_”を付けることがプラクティスとして推奨されます。
verコードの例:
// このサンプルコードからは、頂点位置データの操作を省略している
// WEBGL/p5からテクスチャ座標を得る
attribute vec2 aTexCoord;
// テクスチャ座標を保持するvarying vec2を作成
varying vec2 vTexCoord;
void main() {
// テクスチャ座標をコピー
vTexCoord = aTexCoord;
}
fragコードの例:
// 頂点シェーダーからのテクスチャ座標
varying vec2 vTexCoord;
void main(){
// uv座標をテクスチャ座標に設定
vec2 uv = vTexCoord;
}