纹理的透明度有时会被忽略

Texture's transparency is sometimes ignored

我在 Android 上开发了一个 OpenGLES 2.0 应用程序,并将纹理映射到我的一些对象。这些纹理是从具有透明位的位图创建的,但在渲染时有时透明位是真正透明的,有时它们是黑色的

在这两种情况下,我使用相同的纹理创建和着色器代码。

这是纹理加载...

Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), id);
// If something went wrong delete the texture and return 0
if (bitmap == null) {
    return 0;
}


final int[] textureID = new int[1];
GLES20.glGenTextures(1, textureID, 0);

GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureID[0]);

GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

// Copy the bitmap to the texture
android.opengl.GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);

// Unbind
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);

我用以下渲染

GLES20.glUseProgram(mProgram);

// Prepare the coordinate data
GLES20.glVertexAttribPointer(
        mPositionParam, Mesh.XYZ_COORDS_PER_VERTEX,
        GLES20.GL_FLOAT, false,
        Mesh.XYZ_COORDS_PER_VERTEX * Mesh.BYTES_PER_FLOAT, mesh.getVertexBuffer());

// Set the active texture unit to texture unit 0.
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);

// Bind the texture to this unit.
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mesh.getTextureId());

// Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
GLES20.glUniform1i(mTextureParam, 0);

FloatBuffer textureBuffer = useAltTexture && mesh.hasStereoTexture() ?
        mesh.getStereoTextureBuffer() : mesh.getTextureBuffer();
GLES20.glVertexAttribPointer(
        mTexturePosParam, Mesh.UV_COORDS_PER_VERTEX,
        GLES20.GL_FLOAT, false,
        Mesh.UV_COORDS_PER_VERTEX * Mesh.BYTES_PER_FLOAT, textureBuffer);


GLES20.glUniformMatrix4fv(mModelViewProjectionParam, 1, false, modelViewProjection, 0);
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
// Draw the shape
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, mesh.getVertexCount());
GLES20.glDisable(GLES20.GL_BLEND);

我的顶点着色器:

uniform mat4 u_MVPMatrix;

attribute vec4 a_Position;
attribute vec2 a_TexCoord;

varying vec2 v_TexCoord;

void main() {
    // The matrix must be included as a modifier of gl_Position.
    // Note that the u_MVPMatrix factor *must be first* in order
    // for the matrix multiplication product to be correct.
    v_TexCoord = a_TexCoord;
    gl_Position = u_MVPMatrix * a_Position;
}

我的片段着色器:

precision mediump float;

varying vec2 v_TexCoord;

uniform sampler2D u_Texture;

void main() {
    gl_FragColor = texture2D(u_Texture, v_TexCoord);
}

关于为什么混合不一致的任何线索?

因为透明像素仍会创建深度缓冲区条目,所以您必须遵循painter's algorithm

但是,您可以使用“discard”关键字丢弃 glsl 中的像素。

 if (color.rgb == vec3(0.0,0.0,0.0)) 
  discard;
else
  fragColor = vec4(color, 1.0);