背景信息:我在iOS 11上使用OpenGLES 2进行以下所有操作
在实现用于将两个纹理混合在一起的不同混合模式时,我遇到了一个奇怪的问题,我设法将其缩减为以下内容:
我试图将以下两个纹理混合在一起,只使用片段着色器而不是OpenGL混合函数或方程。 GL_BLEND已停用。
底部 - dst:
热门 - src:
(底部图像与顶部图像相同,但旋转并混合到不透明的白色背景上,使用"普通"(如在Photoshop'普通'中)混合)
为了进行混合,我使用
#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中制作):
在两个纹理都包含大于任意阈值的红色的区域中,所有处都是红色和绿色/黄色。
但是,我得到的结果由于某种原因取决于我为红色分量(0.6
或0.8
)选择的输出值,并且这些输出都不匹配预期的输出值。
这就是我所看到的(灰色边框只是背景):
案例1:
案例2:
总结一下:如果我返回一个大于阈值的红色值,例如
return vec4(0.8, g, 0.0, 1.0);
我看到垂直的黄线,而如果红色组件小于阈值,则结果中没有黄色/绿色。
问题:
为什么我的片段着色器的输出决定条件语句是否被执行,即便如此,为什么我最终会使用绿色垂直线而不是绿色框(这表示dstColor未被正确读取)?
是否与我正在使用的扩展程序有关?
我还想指出纹理都被正确加载和绑定。如果我只是在没有混合的情况下返回单独的纹理信息,或者甚至使用我已经实现的一切正常混合功能,我可以看到它们很好。
答案 0 :(得分:0)
我发现问题是什么(我意识到这不是任何人只是通过阅读问题就知道的事情):
您可以在上面看到的两个纹理之间绘制一个额外的完全透明纹理,这是我忘记的。
透明纹理的颜色信息(dstColor
,而不是考虑到这一点,只是在srcColor
alpha为0
的情况下返回(0.0, 0.0, 0.0, 0.0)
。 )在混合时使用,因此改变帧缓冲内容。
透明纹理和最终纹理都是使用blendTest
函数绘制的,因此在混合最终纹理时会读入第一个函数调用的输出。