Opengl es 如何使Alpha混合透明度在OpenGL ES 2.0中工作?

Opengl es 如何使Alpha混合透明度在OpenGL ES 2.0中工作?,opengl-es,opengl-es-2.0,transparency,alpha,Opengl Es,Opengl Es 2.0,Transparency,Alpha,我正在将一些代码从OpenGLES1.x移植到OpenGLES2.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); 我的着色器如下所示: at

我正在将一些代码从OpenGLES1.x移植到OpenGLES2.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;
}
出了什么问题

编辑:如果我按照的建议在片段着色器(或实际上在顶点着色器)中手动将片段着色器中的alpha设置为
0.5
,那么我将获得透明的所有内容。此外,如果我将传递给OpenGL的颜色值更改为浮点值而不是无符号字节,则代码可以正常工作

因此,将颜色信息传递到OpenGL的代码似乎有问题,我仍然想知道问题出在哪里

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

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


上面的错误是什么?

我怀疑根据片段着色器变化的DestinationColor始终包含alpha通道的0xFF?如果是这样,那就是你的问题。尝试改变它,使alpha实际发生变化

更新:我们发现了两个很好的解决方案:

  • 为片段着色器中提供给DestinationColor的变量使用浮点而不是无符号字节

  • 或者,正如GuyRT所指出的,您可以将glVertexAttributePointer的第四个参数更改为GL_TRUE,以告知OpenGL ES在值从整数转换为浮点数时规范化这些值


  • 要调试这种情况,您可以尝试设置常量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 | ES 2.0的规范(第4.5.3节),请查看以下答案:

    您的颜色顶点属性值未被规范化。这意味着顶点着色器会看到该属性在0-255范围内的值

    glvertexattributepointer
    的第四个参数更改为
    GL_TRUE
    ,这些值将按照您最初的预期标准化(缩放到0.0-1.0的范围)


    谢谢。这很有帮助。看起来我传递无符号字节的方式有问题。(请参见编辑到问题)有什么想法吗?我认为它实际上总是包含1,但你是对的,一旦它到达片段着色器,它就错了。(请参见上面的编辑。)有什么想法吗?输入颜色值必须在0.0到1.0范围内浮动。因为您使用的是字节,所以0以上的所有整数值都被转换为1.0及以上的值,饱和为1.0,使您完全不透明。谢谢!我想这就是正在发生的事情,但我没有意识到这仅仅是因为在OpenGL ES 2.0中不能使用无符号字节作为颜色。如果您编辑您的答案以包含此信息,我将删除我的答案并接受您的答案。您可以使用字节作为颜色。只需将
    glvertexattributepointer
    的第四个参数更改为
    GL_TRUE
    ,这些值将按照您最初的预期进行规范化。可能不会像我意识到代码中有一个bug完全未定义该标志时那样愚蠢!
    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);
    
    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 */
    }