片段着色器输出干扰条件语句
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.6
或 0.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
函数绘制的,因此在混合最终纹理时会读入第一个函数调用的输出。
上下文:我在 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.6
或 0.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
函数绘制的,因此在混合最终纹理时会读入第一个函数调用的输出。