如何在OpenGL ES 2.0中使用Alpha混合透明度?

时间:2013-06-12 17:19:24

标签: opengl-es opengl-es-2.0 transparency alpha

我正在将一些代码从OpenGL ES 1.x移植到OpenGL ES 2.0,而我正在努力让透明度像以前一样工作;我的所有三角形都呈现为完全不透明。

我的OpenGL设置包含以下几行:

// Draw objects back to front
glDisable(GL_DEPTH_TEST);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glDepthMask(false);

我的着色器看起来像这样:

attribute vec4 Position;
uniform highp mat4 mat;
attribute vec4 SourceColor;
varying vec4 DestinationColor;

void main(void) {
  DestinationColor = SourceColor;
  gl_Position = Position * mat;
}

和此:

varying lowp vec4 DestinationColor;

void main(void) {
  gl_FragColor = DestinationColor;
}

可能出现什么问题?

编辑:如果我按照keaukraine below的建议手动将片段着色器中的alpha设置为片段着色器(或实际上是顶点着色器)中的0.5,那么一切都透明了。 此外,如果我将传入OpenGL的颜色值更改为浮点数而不是无符号字节,则代码可以正常工作。

所以看起来将颜色信息传递给OpenGL的代码有问题,我仍然想知道问题是什么。

我的顶点定义如下(与OpenGL ES 1.x代码相同):

typedef struct
{
  GLfloat x, y, z, rhw;
  GLubyte r, g, b, a;
} Vertex;

我使用以下代码将它们传递给OpenGL(类似于OpenGL ES 1.x代码):

glBindBuffer(GL_ARRAY_BUFFER, glTriangleVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * nTriangleVertices, triangleVertices, GL_STATIC_DRAW);
glUniformMatrix4fv(matLocation, 1, GL_FALSE, m);
glVertexAttribPointer(positionSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, x));
glVertexAttribPointer(colorSlot, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, r));
glDrawArrays(GL_TRIANGLES, 0, nTriangleVertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);

以上是什么问题?

3 个答案:

答案 0 :(得分:5)

您的颜色顶点属性值未正常化。这意味着顶点着色器可以看到该属性的值,范围为0-255。

glVertexAttribPointer的第四个参数更改为GL_TRUE,并按正常预期将值标准化(缩放到0.0-1.0范围)。

请参阅http://www.khronos.org/opengles/sdk/docs/man/xhtml/glVertexAttribPointer.xml

答案 1 :(得分:2)

我怀疑到您的片段着色器的DestinationColor变化总是包含Alpha通道的0xFF?如果是这样,那就是你的问题。尝试更改它,以便alpha实际变化。

更新:我们找到了2个好的解决方案:

  1. 对片段着色器中提供给DestinationColor的变化使用浮点数而不是无符号字节。

  2. 或者,正如GuyRT所指出的,您可以将glVertexAttribPointer的第四个参数更改为GL_TRUE,以告诉OpenGL ES在将它们从整数转换为浮点值时对值进行标准化。

答案 2 :(得分:1)

要调试这种情况,您可以尝试设置常量alpha并查看它是否有所作为:

varying lowp vec4 DestinationColor;

void main(void) {
  gl_FragColor = DestinationColor;
  gl_FragColor.a = 0.5; /* try other values from 0 to 1 to test blending */
}

此外,您应该确保使用Alpha通道选择EGL配置。

不要忘记在片段着色器中指定浮点数的精度!阅读OpenGL GL | ES 2.0(http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf第4.5.3节)的规格,请看这个答案:https://stackoverflow.com/a/6336285/405681