片段着色器输出干扰条件语句

Fragment shader output interferes with conditional statement

上下文:我在 iOS 11

上使用 OpenGLES 2 执行以下所有操作

在实现用于将两个纹理混合在一起的不同混合模式时,我遇到了一个奇怪的问题,我设法将其减少为以下内容:

我正在尝试将以下两个纹理混合在一起,仅使用片段着色器而不是 OpenGL 混合函数或方程。 GL_BLEND 已禁用。

底部 - 夏令时:

顶部 - src:

(底部图像与顶部图像相同,但使用 "normal"(如在 Photoshop 'normal' 中)混合旋转并混合到不透明的白色背景上)

为了进行混合,我使用

#extension GL_EXT_shader_framebuffer_fetch

extension,这样在我的片段着色器中我可以写:

void main()
{
    highp vec4 dstColor = gl_LastFragData[0];
    highp vec4 srcColor = texture2D(textureUnit, textureCoordinateInterpolated);

    gl_FragColor = blend(srcColor, dstColor);
}

blend 本身不执行任何混合。它仅根据统一的 blendMode 整数值选择要应用的正确混合函数。在这种情况下,第一个纹理使用已经测试过的正常混合函数绘制,然后第二个纹理使用以下 blendTest 函数绘制在顶部:

问题来了:

highp vec4 blendTest(highp vec4 srcColor, highp vec4 dstColor) {

    highp float threshold = 0.7; // arbitrary
    highp float g = 0.0;

    if (dstColor.r > threshold && srcColor.r > threshold) {
        g = 1.0;
    }

    //return vec4(0.6, g, 0.0, 1.0); // no yellow lines (Case 1)
    return vec4(0.8, g, 0.0, 1.0); // shows yellow lines (Case 2)
}

这是我期望的输出(在 Photoshop 中制作):

到处都是红色,green/yellow 在两个纹理都包含大于任意阈值的红色的区域。

但是,出于某种原因,我得到的结果取决于我为红色分量(0.60.8)选择的输出值,并且这些输出的 none 与预计一个。 这是我看到的(灰色边框只是背景):

案例一:

案例二:

所以总结一下:如果我return一个大于阈值的红色值,例如

return vec4(0.8, g, 0.0, 1.0);

我看到垂直的黄线,而如果红色分量小于阈值,则结果中不会有任何 yellow/green。

问题:

为什么我的片段着色器的输出确定条件语句是否被执行,即使如此,为什么我最终得到的是绿色垂直线而不是绿色框(这表明 dstColor 没有被正确读取)?

这与我使用的扩展程序有关吗?

我还想指出纹理都被正确加载和绑定。如果我只是 return 没有混合的单个纹理信息,或者甚至使用我已经实现的正常混合功能,我可以很好地看到它们一切都按预期工作。

我发现了问题所在(我意识到这不是任何人通过阅读问题就能知道的):

在上面的两个纹理之间绘制了一个额外的完全透明纹理,我忘记了。

如果 srcColor alpha 是 0,透明纹理的颜色信息(即 (0.0, 0.0, 0.0, 0.0))不是考虑到这一点,而是只返回 dstColor在混合时使用,因此改变帧缓冲区内容。

透明纹理和最终纹理都是使用 blendTest 函数绘制的,因此在混合最终纹理时会读入第一个函数调用的输出。