混合问题从OpenGLES 1.0移植到2.0(iOS)

时间:2013-07-03 20:15:25

标签: ios opengl-es opengl-es-2.0 alphablending opengl-es-1.1

我正在将一个非常简单的代码从OpenGLES 1.0移植到OpenGLES 2.0。

在原始版本中,我启用了混合

glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

我在ES 2.0实现中使用相同的代码,因为我需要将新渲染的四边形与渲染缓冲区中的内容混合(我保留渲染缓冲区,我无法重新渲染场景)

我正在使用纹理(显示从中心到外部的径向渐变的alpha值,alpha从1到0),用作alpha蒙版,仅包含具有不同alpha值的白色像素。我给我的顶点相同的颜色说红色,alpha为100/255。我的背景是透明的黑色。在那之下,我有一个纯白色的表面(UIView)。我渲染了4个四边形。

OpenGLES 1.0的结果(期望的结果) enter image description here

我的观察告诉我片段着色器应该只是:

gl_FragColor = DestinationColor * texture2D(Texture, TexCoordOut);

(我通过尝试不同的顶点和纹理值得出了这个结论。这也是我在一些教程中读到的内容。)

我正在尝试编写一些OpenGL 2.0代码(包括顶点+片段着色器),它会给我与OpenGLES 1.0完全相同的结果,仅此而已。除了在纹理上应用顶点颜色之外,我不需要/想要在片段着色器中进行任何类型的混合。使用简单的着色器,这是我得到的结果: enter image description here

我几乎尝试了*,+,mix的每一个组合我能想到但是我无法重现相同的结果。这是我到目前为止最接近的,但这绝对不是正确的(这也没有任何意义)

varying lowp vec4 DestinationColor;
varying lowp vec2 TexCoordOut;
uniform sampler2D Texture;

void main(void) {
    lowp vec4 texture0Color = texture2D(Texture, TexCoordOut);
    gl_FragColor.rgb = mix(texture0Color.rgb, DestinationColor.rgb, texture0Color.a);
    gl_FragColor.a = texture0Color.a * DestinationColor.a;
}

这个着色器给了我以下内容: enter image description here

3 个答案:

答案 0 :(得分:0)

通过阅读thisthis,可以构建混合函数。

由于您使用的是glBlendFunc而非glBlendFuncSeparate,因此所有4个频道都在混合使用。使用GL_FUNC_ADD参数将输出O设置为O = sS + dD,其中sd是混合参数,SD是源和目的地颜色。

sd参数由glBlendFunc设置。 GL_ONEs设置为(1, 1, 1, 1)GL_ONE_MINUS_SRC_ALPHAd设置为(1-As, 1-As, 1-As, 1-As),其中As是来源的alpha值。因此,您的混合正在执行此操作(以矢量形式):

O = S + (1-As) * D GLSL中的{p> O = mix(D, S, As),或者: gl_FragColor = mix(DestinationColor, TexCoordOut, As)

如果结果看起来不相似,请确认您没有使用glBlend或任何其他可能会改变最终结果外观的OpenGL API。如果这没有帮助,请发布不同输出的屏幕截图。

答案 1 :(得分:0)

使用着色器无法轻松完成此操作,因为混合必须读取当前帧缓冲状态。 您可以通过渲染纹理并将其传递到着色器来实现此目的,如果您可以在帧缓冲区中获得颜色,那么您就可以了。

你的等式是:

gl_FragColor = wouldBeFramebufferColor + (1-wouldBeFramebufferColor.a) * texture0Color;

但为什么要在着色器中进行此操作AFAIK混合未在OpenGL ES 2.0中删除

答案 2 :(得分:0)

愚蠢的错误。我只需要在顶点着色器中对顶点颜色进行标准化,因为我正在传递无符号字节。