cesium icon indicating copy to clipboard operation
cesium copied to clipboard

Make it easier to debug custom shader compile errors

Open ptrgags opened this issue 3 years ago • 2 comments

Right now, the way I debug compilation errors for a custom shader is putting a breakpoint in ShaderProgram.createAndLinkProgram() on one of the lines that throw DeveloperError, and then inspect the variables vsSource and fsSource which contain the complete shader text (custom shader + ModelExperimental shader code + CesiumJS builtin-stuff). But this is cumbersome and might be confusing to explain.

The tricky thing is the shader code is built in stages:

  • CustomShader only has the code the user added
  • ModelExperimental has a ShaderBuilder object when creating draw commands. This contains the complete shader, of which the custom shader is a small portion. This is usually the code I want to look at when debugging since it has more context about attributes and structs in the shader.
  • the draw command has the ShaderProgram which has the full shader (ModelExperimental code + built in renderer code)

It would be great to make some of these more accessible for debugging. Some ideas:

  1. Perhaps the easiest, instead of ShaderProgram throwing a DeveloperError, maybe it could throw a new ShaderCompilationError that includes the vertex and fragment text.
  2. Or just console.error with the shader text
  3. the ShaderBuilder could certainly have a method like getFullFragmentShaderText() that combines the text like it does when building the ShaderProgram, but returns the string. The only tricky part is how would the user access the shader builder, as this is pretty deep in the private API.
  4. a similar method could be used for the ShaderProgram, but again it would be cumbersome to access and would be exposing more private API.

I'm starting to like the sound of 1) then the user could catch the error and handle it as desired.

ptrgags avatar Mar 31 '22 20:03 ptrgags

  1. Perhaps the easiest, instead of ShaderProgram throwing a DeveloperError, maybe it could throw a new ShaderCompilationError that includes the vertex and fragment text.

I like this. And if the event has no listeners, it could throw a DeveloperError, like the pseudocode:

try {
    compileShader();
    compilationEvent.raiseEvent(true);
} catch (error) {
    destroyResources();
    if (compilationEvent.numberOfListeners === 0) {
        throw new DeveloperError("Error generating shader");
    } else {
        compilationEvent.raiseEvent(false);
    }
}

IanLilleyT avatar Apr 29 '22 13:04 IanLilleyT

  1. Or just console.error with the shader text

This is what https://github.com/CesiumGS/cesium/pull/10629 does.

I think this behavior was originally intended in createAndLinkProgram, but it wasn't working because the shader was deleted before calling debugShaders.getTranslatedShaderSource.

Note: the console.error output is the translated shader source. From my tests, it is still close enough to the raw shader code to be useful.

jjhembd avatar Aug 03 '22 02:08 jjhembd