OpenGL ES 2.0 circle texture has visible outline when blending

460 views Asked by At

Blending enabled

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

Texture loaded as

GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, texture, 0);

GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);

Shader is

private static final String VERTEX_SHADER_CODE =
        "uniform mat4 uMVPMatrix;" +
                "attribute vec4 vPosition;" +
                "attribute vec2 aTexCoord;" +
                "varying vec2 vTexCoord;" +
                "void main() {" +
                "  gl_Position = uMVPMatrix * vPosition;" +
                "  vTexCoord = aTexCoord;" +
                "}";

private static final String FRAGMENT_SHADER_CODE =
        "precision mediump float;" +
                "varying vec2 vTexCoord;" +
                "uniform sampler2D sTexture;" +
                "void main() {" +
                "  gl_FragColor = texture2D(sTexture, vTexCoord);" +
                "}";

Clear color:

GLES20.glClearColor(1f, 1f, 1f, 1f);

Antialiasing: 4x

EGL10.EGL_SAMPLE_BUFFERS, 1,
EGL10.EGL_SAMPLES, 4

Texture (white circle with white transparent background):

enter image description here

Output: textures have visible outline

Output

1

There are 1 answers

2
solidpixel On

Your texture isn't entirely white - it's a white circle on a black background. White texels have a 1.0 alpha, black texels have a 0.0 alpha.

Now enable linear filtering around the edge and get a texel sample which is interpolated between a black and white texel, and you're going to get something which is somewhat grey in the color channel, and partially transparent in the alpha channel.

Basically just remember that OpenGL and OpenGL ES use post-multiplied alpha blending, and that the color channel is really important even for texels where the alpha value is zero ...

If you set the color value to white all over, and just have a zero or non-zero alpha it would behave as you expect.