我需要调试一个GLSL程序,但我不知道如何输出中间结果。 是否有可能使用GLSL进行一些调试跟踪(如printf) ?


当前回答

GLSL Shader源代码由图形驱动程序编译和链接,并在GPU上执行。 如果你想调试着色器,那么你必须使用图形调试器,如RenderDoc或NVIDIA Nsight。

其他回答

如果你想在屏幕上可视化一个值的变化,你可以使用类似于这个的热图函数(我用hlsl写的,但很容易适应glsl):

float4 HeatMapColor(float value, float minValue, float maxValue)
{
    #define HEATMAP_COLORS_COUNT 6
    float4 colors[HEATMAP_COLORS_COUNT] =
    {
        float4(0.32, 0.00, 0.32, 1.00),
        float4(0.00, 0.00, 1.00, 1.00),
        float4(0.00, 1.00, 0.00, 1.00),
        float4(1.00, 1.00, 0.00, 1.00),
        float4(1.00, 0.60, 0.00, 1.00),
        float4(1.00, 0.00, 0.00, 1.00),
    };
    float ratio=(HEATMAP_COLORS_COUNT-1.0)*saturate((value-minValue)/(maxValue-minValue));
    float indexMin=floor(ratio);
    float indexMax=min(indexMin+1,HEATMAP_COLORS_COUNT-1);
    return lerp(colors[indexMin], colors[indexMax], ratio-indexMin);
}

然后在像素着色器中输出如下内容:

return HeatMapColor(myValue, 0.00, 50.00);

并且可以了解它在像素之间的变化情况:

当然你可以使用任何你喜欢的颜色。

GLSL Shader源代码由图形驱动程序编译和链接,并在GPU上执行。 如果你想调试着色器,那么你必须使用图形调试器,如RenderDoc或NVIDIA Nsight。

我发现变换反馈是调试顶点着色器的有用工具。您可以使用它来捕获VS输出的值,并在CPU端读取它们,而不必通过光栅化器。

这里是另一个转换反馈教程的链接。

现有的答案都是好东西,但我想分享更多的小宝石,在调试棘手的精度问题在GLSL着色器有价值。对于以浮点数表示的非常大的int数,需要注意正确使用floor(n)和floor(n + 0.5)来实现round()为精确的int。然后,可以通过以下逻辑将字节组件打包到R、G和B输出值中,呈现一个精确int的浮点值。

  // 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;

GLSL沙盒已经相当方便我的着色器。

不是调试本身(被回答为不能调试),而是方便地快速查看输出中的更改。