はじめに
以下の「p5.js の createFilterShader()」を扱った 2つの記事に引き続き、また 「createFilterShader() を扱います。
- p5.js の createFilterShader() を使ったフィルター用シェーダーのお試し - Qiita
- p5.js のフィルター用シェーダー「createFilterShader()」で座標情報を使った着色のお試し - Qiita
今回は、上記の 2つ目で少し試した「createFilterShader() での座標情報の利用」をさらに試してみます。
前回の内容
前回の記事では、以下のように座標情報をそのまま色情報にする、というのを試していました。
この時の処理は、main() で処理されていく個々のピクセルに対して、他のピクセルの値を参照するようなことは行わない形でした。
今回の内容
今回は、前は試していなかった「異なる位置のピクセルの情報を使った処理」を簡単に試してみます。
プログラムを書いてみる
今回のお試し用に書いたプログラムは以下のとおりです。
function setup() {
let fragSrc = `precision highp float;
varying vec2 vTexCoord;
uniform sampler2D tex0;
void main() {
vec4 color = texture2D(tex0, vTexCoord);
if(vTexCoord.x < 0.5) {
vec4 color2 = texture2D(tex0, vec2(vTexCoord.x + 0.2, vTexCoord.y + 0.2));
color.r = color2.b;
}
gl_FragColor = vec4(color.rgb, 1.0);
}`;
createCanvas(400, 400, WEBGL);
background(0);
noStroke();
fill(100, 100, 200);
rect(0, 0, 150, 150);
let s = createFilterShader(fragSrc);
filter(s);
}
キャンバスでの処理の流れは、「背景を黒にする ⇒ キャンバス上の特定の範囲に青系の色の矩形を描画する ⇒ シェーダーを使ったフィルターを適用」となっています。
この中で使っているシェーダーの処理で、「他のピクセルの情報を参照して処理をする」ということを試しています。
具体的には、主に main() の中の部分です。
その処理では、全体の中の特定の範囲でだけ別のピクセルを参照する処理を行います。
具体的には if(vTexCoord.x < 0.5)
という条件で処理を分けている部分のことです。
vTexCoord.x は、x座標の左端から右端を 0 から 1 という範囲の値で取得できます。
0.5未満という条件を指定しているので、他のピクセルを参照した処理が行われるのは、描画領域の左半分のみです。
さらに、その左半分の範囲のピクセルに対する処理では、以下のような処理を適用しています。
vec4 color2 = texture2D(tex0, vec2(vTexCoord.x + 0.2, vTexCoord.y + 0.2));
color.r = color2.b;
この処理では、ある処理対象のピクセルの色を決める際に、x方向と y方向のそれぞれに 幅と高さのそれぞれ 20%の距離離れた位置のピクセルの値を使っています。
具体的には、その離れた位置にあるピクセルの青色成分の値を、処理対象のピクセルの赤色成分の値に代入しています。
これにより、フィルター適用後のキャンバスでは、描画範囲の一部に赤色の成分をもった部分が出現することになります(上記の「キャンバス上の特定の範囲に青系の色の矩形を描画する」という処理で描画した内容が元になり、赤色の部分が出てきます)。
実行結果
上記のプログラムを実行した結果は、以下のとおりです。
キャンバス内の左半分の領域の中に、赤い矩形が描画されています。
別の位置にあるピクセルの値を使う際に、以下のように x方向と y方向のそれぞれに 幅と高さのそれぞれ 20%の距離離れた位置のピクセルの値を使うということを行ったため、青系の色の矩形の領域と少しずれた位置に赤の矩形が出現しています。
vec4 color2 = texture2D(tex0, vec2(vTexCoord.x + 0.2, vTexCoord.y + 0.2));
ちなみに、シェーダーを使ったフィルターを適用しなかった場合の描画(例えば filter(s)
をコメントアウトした場合の実行結果)は、以下となります。
上で示していた描画結果の赤色の矩形の部分は、シェーダーによるフィルター処理で出現したものであるため、シェーダーを使ったフィルターを適用しない状態にすると、以下のように青系の色の矩形のみが描画されることになります。
青系の色の矩形が描画されるのは、シェーダーを用いたフィルターを適用する処理の前に書いていた、以下の部分によるものです。
fill(100, 100, 200);
rect(0, 0, 150, 150);
今回は、あるピクセルの処理に対して、別の位置にある 1つのピクセルの値を用いた処理を行いましたが、別の位置にある複数のピクセルを用いた処理を行うと、いろいろ面白い見た目のものを作ることもできそうです。