はじめに
p5.jsのWebGL blendは通常、blendModeでしかいじることを想定されていない。しかし人によってはgl.blendFuncで独自に決めたいかもしれない。それを実現するための方法。
コード全文
function setup() {
createCanvas(400,400,WEBGL);
const gl = drawingContext;
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
console.log(gl.getParameter(gl.BLEND_SRC_RGB)); // 770
background(0);
sphere(100);
console.log(gl.getParameter(gl.BLEND_SRC_RGB)); // 1
// 1にされている
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
console.log(gl.getParameter(gl.BLEND_SRC_RGB)); // 770
background(0);
box(100);
console.log(gl.getParameter(gl.BLEND_SRC_RGB)); // 770
// 以降は770が使われる
console.log(gl.isEnabled(gl.BLEND)); // false
blendMode(BLEND);
console.log(gl.isEnabled(gl.BLEND)); // false.
// blendModeを実行してもenableされない。
console.log(gl.getParameter(gl.BLEND_SRC_RGB)); // 依然として770である。
gl.enable(gl.BLEND); // 自前でBLENDを有効化する必要がある。
console.log(gl.isEnabled(gl.BLEND)); // true
// 無事、有効化されました。
// 試してみる。
gl.blendFunc(0, 0); // 全部消す
translate(50,50,50);
torus(80,20,24);
// 消えました。
}
なおバージョンは2.0.5とし、あらかじめ背景を水色にしてある。
手順
とりあえず、コンテキストを取得しましょう。
const gl = drawingContext;
blendFuncを実行します。これで操作できると思うでしょう。実際、値は変化しています。SRC_ALPHAの定数値は770です。
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
console.log(gl.getParameter(gl.BLEND_SRC_RGB)); // 770
しかし描画後に調べてみると...
background(0);
sphere(100);
console.log(gl.getParameter(gl.BLEND_SRC_RGB)); // 1
// 1にされている
描画後に調べると1になっている。どうも描画時に、勝手に1にされてしまうらしい。困ったね。
気を取り直してもう一回やってみる。
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
console.log(gl.getParameter(gl.BLEND_SRC_RGB)); // 770
background(0);
box(100);
console.log(gl.getParameter(gl.BLEND_SRC_RGB)); // 770
// 以降は770が使われる
再度好きなblendFuncを実行し、そのうえで描画し、調べてみる。今度は770だ。つまりこれ以降は770が使われるということ。
ところで、ブレンドは有効になっているのだろうか。
console.log(gl.isEnabled(gl.BLEND)); // false
blendMode(BLEND);
console.log(gl.isEnabled(gl.BLEND)); // false.
// blendModeを実行してもenableされない。
console.log(gl.getParameter(gl.BLEND_SRC_RGB)); // 依然として770である。
実はこの状態でblendMode(BLEND)を実行してもブレンドは有効化されない。明示的に有効化する必要がある。
gl.enable(gl.BLEND); // 自前でBLENDを有効化する必要がある。
console.log(gl.isEnabled(gl.BLEND)); // true
// 無事、有効化されました。
ブレンドが使えるかどうか試してみよう。すべての係数を0にする。この場合、ドローコールが為されたところはすべての色が消えて実質eraseのようになる。
// 試してみる。
gl.blendFunc(0, 0); // 全部消す
translate(50,50,50);
torus(80,20,24);
これで冒頭の画像になる。つまり、消える。ブレンドは有効になっています。
おわりに
なおp5.jsのWEBGLでは、blendは描画時のみ有効になっているようで、描画の外で実行してもisEnabledは常にfalseのようです。じゃあ実行しなくてもいいのかと言えばそうではなくて、明示的に実行しない場合カスタムブレンドは使われない仕組みになっているようです...なんじゃこりゃ。それはさておき、自前でblendを設定する機会があるかどうか知らないですが、場合によっては便利かもしれないですね。
ここまでお読みいただいてありがとうございました。
