How to debug a GLSL shader?

后端 未结 11 1327
青春惊慌失措
青春惊慌失措 2020-11-28 17:38

I need to debug a GLSL program but I don\'t know how to output intermediate result. Is it possible to make some debug traces (like with printf) with GLSL ?

相关标签:
11条回答
  • 2020-11-28 18:17

    The GLSL Shader source code is compiled and linked by the graphics driver and executed on the GPU.
    If you want to debug the shader, then you have to use graphics debugger like RenderDoc or NVIDIA Nsight.

    0 讨论(0)
  • 2020-11-28 18:18

    You can't easily communicate back to the CPU from within GLSL. Using glslDevil or other tools is your best bet.

    A printf would require trying to get back to the CPU from the GPU running the GLSL code. Instead, you can try pushing ahead to the display. Instead of trying to output text, output something visually distinctive to the screen. For example you can paint something a specific color only if you reach the point of your code where you want add a printf. If you need to printf a value you can set the color according to that value.

    0 讨论(0)
  • 2020-11-28 18:23

    I am sharing a fragment shader example, how i actually debug.

    #version 410 core
    
    uniform sampler2D samp;
    in VS_OUT
    {
        vec4 color;
        vec2 texcoord;
    } fs_in;
    
    out vec4 color;
    
    void main(void)
    {
        vec4 sampColor;
        if( texture2D(samp, fs_in.texcoord).x > 0.8f)  //Check if Color contains red
            sampColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);  //If yes, set it to white
        else
            sampColor = texture2D(samp, fs_in.texcoord); //else sample from original
        color = sampColor;
    
    }
    

    enter image description here

    0 讨论(0)
  • 2020-11-28 18:25

    I have found Transform Feedback to be a useful tool for debugging vertex shaders. You can use this to capture the values of VS outputs, and read them back on the CPU side, without having to go through the rasterizer.

    Here is another link to a tutorial on Transform Feedback.

    0 讨论(0)
  • 2020-11-28 18:25

    The existing answers are all good stuff, but I wanted to share one more little gem that has been valuable in debugging tricky precision issues in a GLSL shader. With very large int numbers represented as a floating point, one needs to take care to use floor(n) and floor(n + 0.5) properly to implement round() to an exact int. It is then possible to render a float value that is an exact int by the following logic to pack the byte components into R, G, and B output values.

      // Break components out of 24 bit float with rounded int value
      // scaledWOB = (offset >> 8) & 0xFFFF
      float scaledWOB = floor(offset / 256.0);
      // c2 = (scaledWOB >> 8) & 0xFF
      float c2 = floor(scaledWOB / 256.0);
      // c0 = offset - (scaledWOB << 8)
      float c0 = offset - floor(scaledWOB * 256.0);
      // c1 = scaledWOB - (c2 << 8)
      float c1 = scaledWOB - floor(c2 * 256.0);
    
      // Normalize to byte range
      vec4 pix;  
      pix.r = c0 / 255.0;
      pix.g = c1 / 255.0;
      pix.b = c2 / 255.0;
      pix.a = 1.0;
      gl_FragColor = pix;
    
    0 讨论(0)
  • 2020-11-28 18:28

    GLSL Sandbox has been pretty handy to me for shaders.

    Not debugging per se (which has been answered as incapable) but handy to see the changes in output quickly.

    0 讨论(0)
提交回复
热议问题