Opengl es OpenGL ES片段着色器显然不可能返回白色

Opengl es OpenGL ES片段着色器显然不可能返回白色,opengl-es,glsl,glsles,Opengl Es,Glsl,Glsles,这是一个奇怪的。我有一个片段着色器,据我所知,它只能返回黑色或红色,但它以白色渲染像素。如果我去掉一条特定的线,它会返回我期望的颜色。它可以在WebGL中工作,但不能在Raspberry Pi上的OpenGL ES中工作 这是着色器代码。如果像素表示Mandelbrot集中的一个点,则返回黑色,否则返回红色 precision mediump float; varying vec2 vPosition; void main(void) { float cx = vPosition.x

这是一个奇怪的。我有一个片段着色器,据我所知,它只能返回黑色或红色,但它以白色渲染像素。如果我去掉一条特定的线,它会返回我期望的颜色。它可以在WebGL中工作,但不能在Raspberry Pi上的OpenGL ES中工作

这是着色器代码。如果像素表示Mandelbrot集中的一个点,则返回黑色,否则返回红色

precision mediump float;

varying vec2 vPosition;

void main(void) {
    float cx = vPosition.x;
    float cy = vPosition.y;

    float x = 0.0;
    float y = 0.0;
    float tempX = 0.0;
    int runaway = 0;
    for (int i=0; i < 100; i++) {
         tempX = x * x - y * y + float(cx);
         y = 2.0 * x * y + float(cy);
         x = tempX;
         if (runaway == 0 && x * x + y * y > 100.0) {
             runaway = i;
         }
    }

    if (runaway != 0) {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    } else {
        gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
    }
}
…然后,正如您所期望的,它将所有像素都涂成黑色(因为它总是在最后一个
if
else
分支中结束)

渲染白色像素是某种错误条件的症状吗?如果是,那会是什么


[编辑]在任何人询问之前--设置
runaway=1在那一行也会导致全白屏幕。

我认为问题在于你对目标设备的片段着色器做了太多的工作。您将
runaway
设置为
i
1
的实验允许优化器完全删除循环,这就是您再次看到预期结果的原因

OpenGL ES着色器语言中的一些相关引用:

一般来说,控制流仅限于。。。在编译时可以轻松确定最大迭代次数的循环

对我来说(我在这里有点猜测),这意味着“一些实现根本不支持迭代,并且会展开每个循环”

允许使用非终止循环。超长或非端接环路的后果取决于平台

对我来说,这是在说,“你可以让你的着色器任意迭代,但不一定期望它工作”

是否应该指定迭代次数的限制?决议:不

我觉得OpenGLES 2在着色器复杂性限制方面有点模糊。我认为问题在于:

  • 编译的着色器超出了实现的指令计数限制
  • 着色器执行时间过长,因此在运行时被中断
  • 我认为如果它是#1,您可能会遇到着色器编译器错误、链接器错误或验证错误。您的代码是否彻底检查了这些问题?这可能会澄清一点情况


    无论如何,我认为您必须简化着色器以使其在Raspberry Pi上工作。

    您确定它会返回白色吗?也许您只是在对代码中的帧进行后处理?另外,不建议在着色器中使用条件和循环,尤其是片段。我没有做任何后处理,至少不是有意的:-)如果有任何帮助,您可以在上查看完整代码。我改编它的原始WebGL代码在-,你可以看到它有相同的条件和循环。另外-,据我所知,条件和循环的限制基本上是因为如果所有着色器都在锁步中进行相同的计算,并且不遵循大不相同的代码路径,这会更好。这就是为什么我只是在循环中设置了
    runaway
    ,而不是通过
    break
    或在循环中设置
    &&runaway==0
    条件来退出循环——着色器的所有实例总是进行100次迭代,即使它们不需要。非常感谢!这就是问题所在。当我把迭代次数降到18次时(用一个二进制切块来确定确切的次数),它起了作用,当然Mandelbrot集看起来并不那么好。如果硬件不能处理FS代码,我猜管道的片段部分会返回全白色。哦,我刚刚意识到我没有回答你关于编译器/链接器/验证错误的问题——是的,我想我正在彻底检查它们。至少,坏代码会产生错误。因此,您可以选择#2完整代码(您可以在其中看到错误检查内容)如下:
                 runaway = i;