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.
I figured this out by looking at the source code in p5 Shader class (in the init
function)
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
}