5

我正在将一些代码从 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;
}

可能出了什么问题?

编辑:如果我按照下面的keaukraine0.5的建议将片段着色器中的alpha手动设置为片段着色器(或者实际上是顶点着色器),那么我会得到透明的一切。此外,如果我将传递给 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);

以上有什么问题?

4

3 回答 3

6

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

glVertexAttribPointer更改to的第四个参数,GL_TRUE值将按照您最初的预期进行标准化(缩放到范围 0.0-1.0)。

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

于 2013-06-14T20:44:23.680 回答
2

我怀疑与您的片段着色器不同的 DestinationColor 总是包含 0xFF 的 alpha 通道?如果是这样,那是你的问题。尝试改变它,使 alpha 实际变化。

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

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

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

于 2013-06-12T21:21:43.973 回答
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

于 2013-06-13T07:59:21.193 回答