且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

OpenGL ES 2.0的阿尔法

更新时间:2023-10-07 08:16:28

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

  gl_FragColor =(漫*的Texture2D(u_Texture,v_TexCoordinate));

既然你乘以所有颜色分量,包括α,用,所产生的颜色会尽快漫具有小于1.0的值。由此产生的阿尔法将乘以你从质地得到了阿尔法。

如果你想使用你从质地为你片段的alpha采样的α,你不应该乘以漫。在code只乘以 RGB分量漫可能看起来像这样:

  vec4 texVal =的Texture2D(u_Texture,v_TexCoordinate);
gl_FragColor = vec4(漫* texVal.rgb,texVal.a);

I am trying to load a texture PNG ( exported by photoshop) and use it in OpenGL ES 2.0 in Android, but the solid color seems like transparent ( black circle in the png is totally black)

I has been read that if you scale a png more than 50% that bug appear( I tested with scaling more and same so I supposed that is not the case)

I also read that BitmapFactory dont read premultiplied alpha PNG ,I tryed another fuction that supposed that do the work but didnt work( maybe it was wrong)

Any ways to achieve the correct alpha?

This is my fragment shader:

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));                                       
}

This is my draw call:

    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);

This is my load function;

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];
}

Not sure if there could be a problem with the texture itself as well, but there's definitely something in your shader code that could give you unexpected results:

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

Since you're multiplying all color components, including the alpha, with diffuse, the resulting color will be partially transparent as soon as diffuse has a value less than 1.0. The resulting alpha will be diffuse multiplied by the alpha you got from the texture.

If you want to use the alpha that you sampled from the texture as the alpha of your fragment, you should not multiply it with diffuse. The code to only multiply the RGB components with diffuse could look like this:

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