在GLSL中使用浮点变量作为迭代器时如何避免循环中重复次数的上限?

问题描述 投票:0回答:1

我正在使用 OpenGL 制作一个简单的片段着色器可视化工具,以轻松显示和使用 GLSL 片段着色器。我正在使用 GLFW 用 C 语言制作它。当然,我的参考是shadertoy,我认为它是用WebGL 2.0制作的。

在尝试移植使用浮点变量作为循环迭代器的着色器时,我遇到了奇怪的行为,有效地将每次循环计数限制为两个。相同的着色器在 Shaderoy 中按预期执行。另一方面,如果我使用整数作为迭代器,则不会出现任何问题,并且所有重复都会按预期执行。我的应用程序设法移植任何未成功执行浮点循环的 Shadertoy 着色器。

这个链接表示 GLSL 支持浮动循环。难道是我使用的 GLSL 编译器限制了这些循环,而 WebGL 2.0 却没有?或者也许有选项和/或 OpenGL 设置来防止循环受到限制?我是否缺少改变此行为的标志?

我使用 #version 330 核心作为 GLSL 版本。

这一切都在使用带有集成 Intel GPU 的 MacOS 的 MacBook Pro 上进行了测试。我知道硬件能够执行浮点循环,因为我在shadertoy 中没有任何问题。也许 WebGL 和 GLFW 在 MacOS 上使用不同的图形驱动程序或 OpenGL 实现?

`

#define N 40.0

 void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
    float acc = 0.0, s = 1.0 / N;
    for (float n = 0.0; n < N; n++) {
        acc += s;
    }
    fragColor = vec4(acc, 0.0, 0.0, 1.0);
}

`

这是我正在测试的 GLSL 片段着色器。当执行所有循环重复时,它应该在整个屏幕上输出饱和的红色。这就是在 Shadertoy 中发生的情况,但在我的应用程序中它会产生非常深的红色,相当于循环仅迭代两次。

我尝试在 for 循环之外声明和定义迭代器,具体递增 1.0,使用 while 循环,但没有成功。使用浮点数时只需两次迭代。

opengl gpu glsl shader glsles
1个回答
0
投票

可能发生的情况是编译器错误地估计了可能的最大迭代次数。

3.3 版本的 OpenGL 着色语言规范明确指出

Non-terminating loops are allowed. The consequences of very long or non-terminating loops are platform dependent.
(这并非 3.3 版本所独有)。实际上,大多数 GLSL 编译器都会展开循环,而不是实际循环,不支持这些“非常长”的循环。虽然您的循环不是那么长,但浮点数可能会欺骗编译器。在这种情况下,它很可能会产生警告,您应该检查编译日志,可通过
glGetShaderInfoLog
函数检索。

如果问题确实与不正确的展开有关,您可以尝试一些编译器特定的提示,了解应该期望多少次迭代。但它们是邪恶的魔法,绝对不推荐。

© www.soinside.com 2019 - 2024. All rights reserved.