2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

p5jsでshaderのコンパイルエラーを取得する

Posted at

結論のソースコード


let myShader;
let vertCode;
let fragCode;

function preload() {
  // 頂点シェーダーは変更しないので事前に読み込む
  vertCode = `
    precision highp float;
    // p5.jsのデフォルトの頂点位置属性
    attribute vec3 aPosition;
    void main() {
      gl_Position = vec4(aPosition, 1.0);
    }
  `;
}

function setup() {
  createCanvas(windowWidth, windowHeight, WEBGL);

  // 初期シェーダーを設定
  fragCode = `
    precision highp float;
    void main() {
      vec3 color = vec3(0.0, 0.0, 1.0);
      gl_FragColor = vec4(color, 1.0);
    }
  `;
  myShader = createShader(vertCode, fragCode);
  shader(myShader); // なぜかshader()を実行しないとコンパイルされない
}

function draw() {
  background(220);

  myShader.setUniform("u_time", millis() / 1000.0);
  noStroke();
  shader(myShader);
  quad(-1, -1, -1, 1, 1, 1, 1, -1);
  resetShader();
}

function mouseClicked() {
  console.log("mouseClicked");

  // シェーダーを切り替える
  fragCode = `
    precision highp float;
    uniform float u_time;
    uniform vec2 u_mouse;
    void main() {
      vec3 color = vec3(sin(u_time) * 0.5 + 0.5, 0, 0);
      gl_FragColor = vec4(color, 1.0);
      あえてエラーを起こすコード
    }
  `;

  const compilingShader = createShader(vertCode, fragCode);
  shader(compilingShader); // shaderを実行しないとコンパイルされない

  // コンパイルエラーのチェック
  const gl = compilingShader._renderer.GL;
  const frag_compile_status = gl.getShaderParameter(
    compilingShader._fragShader,
    gl.COMPILE_STATUS
  );
  if (frag_compile_status == false) {
    print("shaderコンパイルエラー");
  } else {
    myShader = compilingShader;
  }
}

Image from Gyazo

マウスクリック時にエラーの出てしまうシェーダーに切り替えてしまいますが、コンパイルエラーを検出しています。
もしコンパイルエラー検出がなくて、myShaderにそのまま代入してしまうと、他の箇所でmyShaderを使うときにエラーが出てしまいます。

できなかったこと

  • try...catch
    • p5js内部では、console.errorを出しているだけなので、catchできません
  • loadShaderの第四引数
    • https://p5js.org/reference/p5/loadShader/
    • jsコード内でshaderのコードを書くのではなく、ファイルに保存してやる方法
    • コンパイルエラーは関係なくファイルロードのエラーの検出なので、コンパイルエラーは検出されない
  • createCanvasで取得するcanvasオブジェクトから、webgl2の取得

myCanvas = p5.createCanvas(400, 400, p5.WEBGL);
gl = myCanvas.elt.getContext('webgl2'); // 中身がなかった

利用用途

ちなみにコンパイルエラーのメッセージ内容取得


const messageFrag = gl.getShaderInfoLog(myShader._fragShader);

こんな感じで取得できました
作ったものでは、AIが作ったコードのコンパイルエラーをまたエラーメッセージと一緒にAIへ渡して、コードを修正させてみています。
工夫ができそうです。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?