2015-05-26 256 views
0

我想加载纹理PNG(由photoshop导出)并将其用于Android中的OpenGL ES 2.0,但纯色看起来像透明(png中的黑色圆圈完全是黑色)OpenGL ES 2.0 Alpha

Error PNG

我已阅读,如果您缩放一个PNG超过50%这个bug出现(我用缩放更多,同样的测试,所以我认为事实并非如此)

我也读了BitmapFactory不要读预乘alpha PNG,我尝试了另一个功能,假设做的工作,但没有工作(也许这是错的)

任何方法来实现正确的阿尔法?

这是我的片段着色器:

precision mediump float;  // Set the default precision to medium. We don't need as high of a 
          // precision in the fragment shader. 
uniform vec3 u_LightPos;  // The position of the light in eye space. 
uniform sampler2D u_Texture; // The input texture. 

varying vec3 v_Position;  // Interpolated position for this fragment. 
varying vec3 v_Normal;   // Interpolated normal for this fragment. 
varying vec2 v_TexCoordinate; // Interpolated texture coordinate per fragment. 

// The entry point for our fragment shader. 
void main()       
{        
    // Will be used for attenuation. 
    float distance = length(u_LightPos - v_Position);     

    // Get a lighting direction vector from the light to the vertex. 
    vec3 lightVector = normalize(u_LightPos - v_Position);     

    // Calculate the dot product of the light vector and vertex normal. If the normal and light vector are 
    // pointing in the same direction then it will get max illumination. 
    float diffuse = max(dot(v_Normal, lightVector), 0.0);                     

    // Add attenuation. 
    diffuse = diffuse * (1.0/(1.0 + (0.25 * distance))); 

    // Add ambient lighting 
    diffuse = diffuse + 0.7; 

    // Multiply the color by the diffuse illumination level and texture value to get final output color. 
    gl_FragColor = (diffuse * texture2D(u_Texture, v_TexCoordinate));          
} 

这是我的绘制调用:

GLES20.glEnable(GLES20.GL_BLEND); 

    GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); 
    GLES20.glUseProgram(mMagiaProgramHandle); 

    mMagiaTextureCoordinateHandle = GLES20.glGetAttribLocation(mMagiaProgramHandle, "a_TexCoordinate"); 
    mTexturePruebaUniformHandle = GLES20.glGetUniformLocation(mMagiaProgramHandle, "u_TextureVec"); 


    coordinate.drawMagia(mPositionHandle, mNormalHandle, mMagiaTextureCoordinateHandle); 

    // This multiplies the view matrix by the model matrix, and stores the 
    // result in the MVP matrix 
    // (which currently contains model * view). 

    Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0); 
    // Pass in the modelview matrix. 
    GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mMVPMatrix, 0); 


    // This multiplies the modelview matrix by the projection matrix, and 
    // stores the result in the MVP matrix 
    // (which now contains model * view * projection). 
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0); 

    // Pass in the combined matrix. 
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0); 

    // Pass in the light position in eye space. 
    GLES20.glUniform3f(mLightPosHandle, mLightPosInEyeSpace[0], mLightPosInEyeSpace[1], mLightPosInEyeSpace[2]); 

    GLES20.glUniform2f(mTexturePruebaUniformHandle, Magia.posTextureX, Magia.posTextureY); 
    // Draw the square. 
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6); 
    GLES20.glDisable(GLES20.GL_BLEND); 

这是我的加载功能;

public static int loadTexture(final Context context, final int resourceId) 
{ 
    final int[] textureHandle = new int[1]; 

    GLES20.glGenTextures(1, textureHandle, 0); 

    if (textureHandle[0] != 0) 
    { 
     final BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inScaled = false; // No pre-scaling 


     // Read in the resource 
     final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, options); 

     // Bind to the texture in OpenGL 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]); 

     // Set filtering 
     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_NEAREST); 

     // Load the bitmap into the bound texture. 
     GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 

     // Recycle the bitmap, since its data has been loaded into OpenGL. 
     bitmap.recycle();      
    } 

    if (textureHandle[0] == 0) 
    { 
     throw new RuntimeException("Error loading texture."); 
    } 

    return textureHandle[0]; 
} 

回答

1

不知道是否有可能是与本身的质感,以及一个问题,但肯定有东西在你的着色器代码,可以给你带来意想不到的结果:

gl_FragColor = (diffuse * texture2D(u_Texture, v_TexCoordinate)); 

既然你乘以所有颜色组件(包括alpha)与diffuse,则只要diffuse的值小于1.0,结果颜色就会部分透明。由此产生的阿尔法将是diffuse乘以你从纹理获得的阿尔法。

如果您想使用从纹理采样的alpha作为片段的alpha值,则不应该将其与diffuse相乘。只将RGB分量与diffuse相乘的代码可能如下所示:

vec4 texVal = texture2D(u_Texture, v_TexCoordinate); 
gl_FragColor = vec4(diffuse * texVal.rgb, texVal.a); 
+0

这是问题所在,谢谢! – D4rWiNS