p5.js のフィルター用シェーダー「createFilterShader()」で WebGL 2.0（GLSL ES 3.0）を使う ＋ 色・座標情報に関わる書き方を WebGL 2.0対応にする

以下の記事でふれた、p5.js で WebGL 2.0（GLSL ES 3.0）を使う話の続きです。

- [p5.js でのシェーダーを使った描画に WebGL 2.0（GLSL ES 3.0）を使う - Qiita](https://qiita.com/youtoy/items/af009f7401fd3ce861dd)

最近、自分が多用していて、そして以下の記事や作品を作成する時にも登場していた「createFilterShader()」も関連する内容を記事にしてみます。

- createFilterShader() 関連
   - [p5.js の createFilterShader() を使ったフィルター用シェーダーのお試し - Qiita](https://qiita.com/youtoy/items/1083d6319ddab6d525d3)
   - [p5.js のフィルター用シェーダー「createFilterShader()」で座標情報を使った着色のお試し - Qiita](https://qiita.com/youtoy/items/b06e65d20aa2f468b8bb)
   - [p5.js のフィルター用シェーダー「createFilterShader()」で座標情報を使った着色のお試し 〜その2〜 - Qiita](https://qiita.com/youtoy/items/9ee8385e2134a09de665)
   - [p5.js のフィルター用シェーダー「createFilterShader()」を使ってメインキャンバスとオフスクリーンキャンバスの描画をまぜる - Qiita](https://qiita.com/youtoy/items/2b4ad4029f651d879d12)

https://twitter.com/youtoy/status/1748002507467763754

## 「createFilterShader()」で WebGL 2.0（GLSL ES 3.0）を使う
どんな内容かというと、「createFilterShader()」を WebGL 2.0対応の書き方で使う、というものです。

「createFilterShader()」は、p5.js でシェーダーを使う際に、バーテックスシェーダーを書かず（デフォルトで用意されているものを使う形）、フラグメントシェーダーだけを書いて、シェーダーを使えるというものです。

その「createFilterShader()」を使ってきた中で、公式リファレンスの記載に従って WebGL 1.0 を組み合わせていた形でした。

そんな中、ふと「createFilterShader() は WebGL 2.0 と組み合わせて、普通に使えるのだろうか？」と思って試してみたら、簡単なものはわりとあっさりできました。そして、そのお試しの内容を、この記事を書いてみました。

さらに以下の ｐ5．ｊｓ公式リファレンスに書かれている WebGL 1.0用のやり方を、WebGL 2.0 に対応した内容にしてみます。

●reference | createFilterShader()
　https://p5js.org/reference/#/p5/createFilterShader

## 実際に試してみる1： 簡単な内容で動作確認
実際に「createFilterShader() と WebGL 2.0 との組み合わせ」を試してみます。
まずは、前の記事で使っていたシンプルな塗りつぶしだけを行う事例で試します。

### プログラムの内容と実行結果
お試し用のプログラムは、以下です。

```javascript
function setup() {
  const fragSrc = `#version 300 es
  precision mediump float;

  out vec4 outColor;

  void main() {
    vec4 myColor = vec4(1.0, 0.0, 0.0, 1.0);
    outColor = myColor;
  }`;

  createCanvas(400, 400, WEBGL);

  let s = createFilterShader(fragSrc);
  filter(s);
}
```

処理内容は、シンプルに「画面全体を赤で塗りつぶす」というものです。

実行結果は以下のとおりで、問題なく WebGL 2.0（GLSL ES 3.0）を利用できているようです。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/71221a1e-ac2a-9715-68bb-b0e7b319d5a0.png)

## 実際に試してみる2： 色・座標情報の入力を WebGL 2.0対応させる
次に「createFilterShader() の公式リファレンスに書かれている内容を、WebGL 2.0 に対応させます。

具体的には以下の部分です。
バーテックスシェーダーから座標の情報を受けとる部分と、その座標情報をキャンバスから受けとった色情報と組み合わせて扱う部分を、Web 2.0用の書き方にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/7fab37d7-3567-175a-8f4e-439110401ee5.png)

書きかえについての概要を書くと、以下のとおりです。

- [WebGL 2.0 では「varying」が廃止されているため、バーテックスシェーダーからフラグメントシェーダへ入力として受け取る部分では「in」を使うよう変更](https://wgld.org/d/webgl2/w003.html)
- 「texture2D関数」が廃止されているため、「texture関数」を使うように変更

### プログラムの内容と実行結果
上記の対応をしたテスト用のプログラムを以下に示します。

```javascript
function setup() {
  const fragSrc = `#version 300 es
  precision mediump float;

  out vec4 outColor;

  in vec2 vTexCoord;
  uniform sampler2D tex0;

  void main() {
    vec4 color = texture(tex0, vTexCoord);
    if(vTexCoord.x < 0.80) {
      color.b = 1.0;
    }
    outColor = color;
  }`;

  createCanvas(400, 400, WEBGL);

  background(220);
  fill(0, 0, 0);
  noStroke();
  rect(80, 50, 90);

  let s = createFilterShader(fragSrc);
  filter(s);
}
```

上記のプログラムを実行して、以下の描画結果が得られました。
そして、意図した挙動になっていることが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/a50505ed-d05b-2613-ead8-816c342d8ce7.png)

素直に、WebGL 1.0用の書き方だったものを、WebGL 2.0用の書き方にするだけで、「createFilterShader()」を WebGL 2.0対応にできました。