本稿は「Basic gradient shader based on texture coordinates」ページを翻訳したものです。
目次
テクスチャ座標にもとづいた基本的なグラデーションシェーダー
このグラデーションは、前の「ピクセル座標にもとづいた基本的なグラデーションシェーダー」のグラデーションと、テクスチャ座標を計算するためにresolution uniformを渡さないという点で、少し異なります。ここではテクスチャ座標を頂点シェーダーから渡します。。それはCPUから受け取ったものです。小さな違いですが注目する価値はあります。
.jsファイル
// シェーダー変数
let theShader;
function preload() {
// シェーダーをロードする
theShader = loadShader('basic.vert', 'basic.frag');
}
function setup() {
// シェーダーを動作させるにははWEBGLモードが必要
createCanvas(windowWidth, windowHeight, WEBGL);
noStroke();
}
function draw() {
// アクティブなシェーダーをtheShaderに設定する
shader(theShader);
// rect()で画面にジオメトリを与える
rect(0, 0, width, height);
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}
.vertファイル
// 頂点データ
attribute vec3 aPosition;
// テクスチャ座標 p5から送られて来る
attribute vec2 aTexCoord;
// これは、フラグメントシェーダーと共有する変数。
// テクスチャ座標を頂点シェーダーからフラグメントシェーダに移すために、attribute テクスチャ座標をvarying テクスチャ座標に割り当てる
// 好きな名前が付けられるが、varyingであることを示すために頭に'v'を付ける人が多い
varying vec2 vTexCoord;
void main() {
// テクスチャ座標をコピーする
vTexCoord = aTexCoord;
vec4 positionVec4 = vec4(aPosition, 1.0);
positionVec4.xy = positionVec4.xy * 2.0 - 1.0;
// 頂点情報をフラグメントシェーダーに送る
gl_Position = positionVec4;
}
.fragファイル
precision mediump float;
// これは、頂点シェーダーで宣言したものと同じ変数
// ここでも宣言する必要がある
varying vec2 vTexCoord;
void main() {
// vTexCoordをコピーする
// vTexCoordは、ピクセル位置に応じて、0.0から1.0まで変化する
// これを使うと、画面の全ピクセルにアクセスできる
vec2 coord = vTexCoord;
// x値を赤、y値を緑、xとy値の合計を青に当てる
gl_FragColor = vec4(coord.x, coord.y, (coord.x+coord.y), 1.0 );
}
図を使って整理してみる
このサンプルも、図を使って整理しておきましょう。ただし下の図では、キャンバスを400 x 300で作成しています描くのは、前のサンプルと同じ黒から赤へのグラデーションです。
sketch.jsから頂点シェーダーには、頂点情報のaPositionに加え、テクスチャ座標情報を持ったaTexCoordも送られます。この情報は、下図に示すように、矩形ならその4隅を(0,0),(1,0),(1,1),(0,1)に定めたuv座標と考えられます。
頂点シェーダーではこれをattribute vec2 aTexCoord; で受け取ります。そしてフラグメントシェーダーに送れるように、varying vec2 vTexCoord;も宣言しておきます(「p5.js shader スタート 7 変数修飾子の使用」を参照)。main()関数でvaryingのvTexCoordにaTexCoordを代入します。これにより、テクスチャ座標の情報がフラグメントシェーダーに自動的に送られます。
フラグメントシェーダーでは、varying vec2 vTexCoord;を宣言しておいて、頂点シェーダーからのvTexCoordを受け取ります。そしてmain()関数でvTexCoordを変数coordにコピーして(上書きできないので)、gl_FragColorにcoord.xを割り当てます。
前のサンプルではvec2 st = gl_FragCoord.xy/u_resolution.xy; という計算を行いましたが、このstに相当するものはテクスチャ座標のcoord(vTexCoord)としてもう得ているので、vec4()関数のR用の引数にはそのまま使用できます。