我该如何调试GLSL着色器?

7

如何调试OpenGL着色器?例如:

void main(void)
{
    vec2 uv = gl_FragCoord.xy;
    gl_FragColor = vec4(uv,222,1);
}

有没有办法可以查找uv值是多少?

我点赞并整理了这个问题,因为我认为这是一个非常值得问的有效问题。 - James Bedford
你可以使用 glReadPixels。如果你有非变量或区域常量值,你甚至可以使用 GLSL 调试打印 打印数字值,但这并不适用于每个像素的 uv 值都不同的情况。 - Spektre
@JamesBedford 难道不需要特定于OS X吗?感觉这是一个可以轻松适用于所有平台的问题,因为所有平台的技术都是相同的。 - Cewein
1个回答

1

调试GLSL着色器


有许多方法可以调试着色器,大多数方法都是视觉方式,而不是输出整个图像的完整像素数据。

由于着色器以高度并行的方式运行,因此您可以一次输出大量的视觉数据。

还有一些外部应用程序可以帮助您大大调试glsl着色器和整个渲染流水线。


视觉调试

这是最简单的调试形式,但结果最难理解。您只需要将要查看的数据输出到屏幕上,例如了解所需的UV值。

您可以像这样执行:

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    // Output to screen
    fragColor = vec4(uv, 0.0 ,1.0);
}

0至1范围内的紫外线强度

在这张图片中,您可以看到标准化UV的范围从0到1。黄色表示UV是vec2(1.0,1.0),黑色表示vec2(0.0,0.0)。

另一个可视化调试的例子:输入图像的描述 (来源:https://www.shadertoy.com/view/ts2yzK)

这是一个光线追踪项目中的示例。此图像中有两个要素,我调试了射线的深度并检查是否有击中。

白色表示命中,黑色表示未命中。

另一方面,此图像不适合显示图像深度。由于存在以下两个问题,您可能会难以调试此类图像:

  • 负值渲染为黑色
  • 超过1.0的值渲染为白色

这样的值会导致我们使用另一种类型的调试。


外部应用程序

https://renderdoc.org/

Renderdoc是最好的调试器之一。虽然还有许多其他调试器,但这个免费使用并具有广泛的使用范围。

您可以通过查看着色器之前和之后来调试顶点GLSL着色器。 您还可以查看片段着色器的每个像素及其值。

您还可以查看GPU上的数据存储方式以及更多信息。


最后的说明

在调试时,无论是可视化的还是非可视化的,您都必须知道在找什么,至少要有一个命中。可视化调试是最难调试的事情之一,因为通常由于着色器的高度并行性而无法逐步执行您的代码。

许多错误也是因为我们忘记了小细节,例如标准化值、忘记负号等更多小细节。

要发现错误并正确调试,您必须认真细致并耐心。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接