OpenGL ES片段着色器显然不可能返回白色 [英] OpenGL ES fragment shader apparently impossibly returning white

查看:95
本文介绍了OpenGL ES片段着色器显然不可能返回白色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这很奇怪.我有一个片段着色器,据我所知只能返回黑色或红色,但是它将像素渲染为白色.如果我删除了一条特定的线,它将返回我期望的颜色.它可以在WebGL中使用,但不能在Raspberry Pi上的OpenGL ES中使用.

This is a weird one. I have a fragment shader that as far as I can tell can only return black or red, but it's rendering the pixels in white. And if I remove one specific line, it returns the colour I'd expect. It works in WebGL, but not in OpenGL ES on the Raspberry Pi.

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

Here's the shader code. It returns black if the pixel represents a point inside the Mandelbrot set, red otherwise.

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);
    }
}

以便着色器将所有像素绘制为白色.但是,如果我删除行

So that shader paints all pixels white. However, if I remove the line

             runaway = i;

...然后,如您所料,它将所有像素涂成黑色(因为它总是在最终ifelse分支中结束).

...then, as you'd expect, it paints all pixels black (because it always winds up in the else branch of the final if).

呈现白色像素是某种错误情况的征兆吗?如果是这样,那会是什么?

Is rendering a white pixel the symptom of some kind of error condition? If so, what could it be?

[edit]在有人问之前-在该行上设置runaway = 1;也会导致全白屏幕.

[edit] Before anyone asks -- setting runaway = 1; on that line also leads to an all-white screen.

推荐答案

我认为问题是您为目标设备的片段着色器做了大量的工作.通过将runaway设置为i1的实验,优化程序可以完全删除循环,这就是为什么您再次开始看到预期结果的原因.

I think the problem is that you're doing too much work for a fragment shader for the target device. Your experiments where you set runaway to i or 1 are allowing the optimizer to remove the loop entirely which is why you start to see expected results again.

OpenGL ES着色器语言规范:

Some relevant quotes from the OpenGL ES Shader Language spec:

通常,控制流限于...循环,可以在编译时轻松确定最大迭代次数.

In general, control flow is limited to ... loops where the maximum number of iterations can easily be determined at compile time.

对我来说(我在这里稍作猜测),这翻译为某些实现根本不支持迭代,并且会展开每个循环"

To me (and I'm speculating a bit here), this translates as "Some implementations don't support iteration at all and will unroll every loop"

允许非终止循环.较长或不终止的循环的后果取决于平台.

Non-terminating loops are allowed. The consequences of very long or non-terminating loops are platform dependent.

对我来说,这是在说:您可以使着色器尽可能多地进行迭代,但不一定希望它能够工作".

To me, this is saying, "You can make your shader iterate as much as you like but shouldn't necessarily expect it to work".

是否应指定迭代次数的限制?解决方案:否

Should a limit on the number of iterations be specified? RESOLUTION: No

我觉得OpenGLES 2对于着色器复杂度限制有点含糊.我认为问题是:

I feel OpenGLES 2 is a bit vague about shader complexity limits. I think the problem is either:

  1. 您编译的着色器超出了实现的指令数限制
  2. 您的着色器执行时间太长,结果在运行时被中断.

我认为,如果它是#1,则可能应该期望着色器编译器错误,链接器错误或验证错误.您的代码是否对这些进行了彻底检查?可能会稍微澄清一下情况.

I think that if it is #1 you should probably expect shader compiler errors, linker errors or validation errors. Does your code check thoroughly for these? It may clarify the situation a little.

无论如何,我认为您必须简化着色器才能使其在Raspberry Pi上运行.

Regardless, I think you'll have to simplify the shader to make it work on Raspberry Pi.

这篇关于OpenGL ES片段着色器显然不可能返回白色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆