纹理的透明度有时会被忽略
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);
我在 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);