捕获着色器编译错误

huangapple go评论75阅读模式
英文:

P5 catch shader compilation errors

问题

我正在在网络上制作一个着色器编辑器。用户可以在文本区域中创建他们自己的着色器,然后将其应用于网络摄像头。

问题是,我没有办法捕获着色器编译错误并将其显示给用户。它们只会在开发者控制台中引发错误。

我的代码

try {
  newShaderObj = pFive.createShader(defaultVertShader, fragShader)
  pFive.shader(newShaderObj)
} catch (e) {
  alert(e)
}

这里的 try / catch 不起作用;我仍然在控制台中看到这个错误,catch 永远不会运行

p5.min.js:2 糟糕!编译片段着色器时发生错误:错误:0:4: 'asd':语法错误

我还收到了另一个错误

p5.min.js:2 未捕获的类型错误:无法执行'WebGLRenderingContext'上的'useProgram':参数1不是'type 'WebGLProgram'。

如果我引入一个全局的 window.onerror 处理程序,我可以救出这个错误:

window.onerror = (ev, source, lineno, colno, err) => {
  alert(err)
  pFive.shader(defaultValidShader)
}

但它不告诉我任何关于底层编译错误的信息。而且,pFive.shader.defaultValidShader 无效,我必须重新加载页面才能再次工作。

所以,我真的想要做的是在应用着色器之前验证/编译着色器,并且有一种处理运行时错误的方式。

英文:

I am making a shader editor in the web. Users can create their own shaders in a textarea and it will be applied to a webcam.

The problem is that I have no watch to catch shader compilation errors and display them to the user. They just raise an error in developer console.

My code

    try {
      newShaderObj = pFive.createShader(defaultVertShader, fragShader)
      pFive.shader(newShaderObj)
    } catch (e) {
      alert(e)
    }

The try / catch here doesn't work; I still get this error shown in console, without the catch ever running

> p5.min.js:2 Darn! An error occurred compiling the fragment shader:ERROR: 0:4: 'asd' : syntax error

I'm also getting this other error

> p5.min.js:2 Uncaught TypeError: Failed to execute 'useProgram' on 'WebGLRenderingContext': parameter 1 is not of type 'WebGLProgram'.

If I introduce a global window.onerror handler, I can rescue this one:

    window.onerror = (ev, source, lineno, colno, err) => {
      alert(err)
      pFive.shader(defaultValidShader)
    }

But it doesn't tell me anything about the underlying compilation error. Also, that pFive.shader.defaultValidShader doesn't work, and I have to reload the page to get anything working again.

So, what I would really like to do is validate/compile the shader before applying it, and also have a way to handle errors at runtime.

答案1

得分: 1

我通过查看p5 Shader类中的源代码(在init函数中)找到了解决方法。

https://github.com/processing/p5.js/blob/64354940c5a116b1b27bbf4c6cb7f04b6c2b9f0a/src/webgl/p5.Shader.js

最终的代码如下:

    newShaderObj = pFive.createShader(defaultVertShader, fragShader)
    shaderError = checkShaderError(shaderObj, fragShader)
    if (shaderError) {
      alert(shaderError)
    } else {
      shaderObj = newShaderObj
      pFive.shader(shaderObj)
    }

还有checkShaderError函数:

  checkShaderError = (shaderObj, shaderText) => {
    gl = shaderObj._renderer.GL
    glFragShader = gl.createShader(gl.FRAGMENT_SHADER)
    gl.shaderSource(glFragShader, shaderText)
    gl.compileShader(glFragShader)
    if (!gl.getShaderParameter(glFragShader, gl.COMPILE_STATUS)) {
      return gl.getShaderInfoLog(glFragShader)
    }
    return null
  }
英文:

I figured this out by looking at the source code in p5 Shader class (in the init function)

https://github.com/processing/p5.js/blob/64354940c5a116b1b27bbf4c6cb7f04b6c2b9f0a/src/webgl/p5.Shader.js

and ended up with the following code:

    newShaderObj = pFive.createShader(defaultVertShader, fragShader)
    shaderError = checkShaderError(shaderObj, fragShader)
    if (shaderError) {
      alert(shaderError)
    } else {
      shaderObj = newShaderObj
      pFive.shader(shaderObj)
    }

And the checkShaderError function:

  checkShaderError = (shaderObj, shaderText) => {
    gl = shaderObj._renderer.GL
    glFragShader = gl.createShader(gl.FRAGMENT_SHADER)
    gl.shaderSource(glFragShader, shaderText)
    gl.compileShader(glFragShader)
    if !gl.getShaderParameter(glFragShader, gl.COMPILE_STATUS) {
      return gl.getShaderInfoLog(glFragShader)
    }
    return null
  }

huangapple
  • 本文由 发表于 2023年2月27日 00:26:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75573386.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定