OpenGL ES 2.0 transparency using alpha testing in shader
I'm trying to make transparent object in OpenGL ES 2.0. I'm setting up GL w/ following params:
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glDepthFunc(GLES20.GL_LESS);
GLES20.glDisable(GLES20.GL_BLEND);
GLES20.glClearDepthf(1.0f);
Here is the code for shaders:
private final String mVertexShader = "uni开发者_运维百科form mat4 uMVPMatrix;\n" +
"attribute vec4 aPosition;\n" +
"attribute vec2 aTextureCoord;\n" +
"varying vec2 vTextureCoord;\n" +
"void main() {\n" +
" gl_Position = uMVPMatrix * aPosition;\n" +
" vTextureCoord = aTextureCoord;\n" +
"}\n";
private final String mFragmentShader = "precision mediump float;\n" +
"varying vec2 vTextureCoord;\n" +
"uniform sampler2D sTexture;\n" +
"void main() {\n" +
" vec4 base = texture2D(sTexture, vTextureCoord);\n" +
" if(base.a < 0.5){ discard; }\n" +
" gl_FragColor = base;\n" +
"}\n";
Resulting images of rendering: http://imgur.com/hNqm0 http://imgur.com/dmS2O. Please tell me what I'm doing wrong, it renders fine in Rendermonkey OpenGL ES mode.
If I use
GLES20.glDisable(GLES20.GL_BLEND);
for initializing OpenGL I get correct transparency but without ordering of triangles. May be some sorting will help in this case?
Alpha blend is supported by OpenGL. You do not need special code in shader. Try setting following:
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc (GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
OK, so I've found the cause of this glitch.
Even though depth test was disabled, and fragment shader discarded certain pixels making them transparent, triangles were still occluded because of writing to depth buffer.
I had to disable writing to depth buffer with this code:
GLES20.glDepthMask(false);
Obviously, writing to depth buffer was disabled in Rendermonkey too, resulting correct image.
Thanks for your answers below, but I don't need to use alpha blending - I have to use alpha testing, and it doesn't require sorting of triangles.
OpenGL does not order your triangles for you. But as you are just doing alpha testing and disable blending, that shouldn't be a problem for you.
I think you should put "gl_FragColor = base;" in 'else' like
private final String mFragmentShader =
"precision mediump float;\n" +
"varying vec2 vTextureCoord;\n" +
"uniform sampler2D sTexture;\n" +
"void main() {\n" +
" vec4 base = texture2D(sTexture, vTextureCoord);\n" +
" if(base.a < 0.1){ discard; }\n" +
" else { gl_FragColor = base; }\n" +
"}\n";
this one
精彩评论