OpenGL透明图像中有黑色

时间:2012-04-29 18:05:14

标签: android opengl-es alpha overlap blending

我正在开发Android游戏,我想知道为什么每当我用透明度绘制图像时,似乎总是会在透明部分添加一些黑色。这种情况一直发生,使我的一些效果看起来很奇怪。

这是一个例子。两个圆圈只是带有模糊的白色图像,但是你可以看到一个圆圈与另一个重叠,它有一个阴影。如果我在Inkscape中说两个圆圈重叠,我会在它们重叠的地方得到纯白色。

enter image description here

我正在使用

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

我的混合。

知道为什么会这样,以及如何避免它?

编辑:我唯一能想到的是两幅图像具有相同的z,所以它们可能只与背景混合而不是相互混合?

编辑: 我改变了

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

GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_DST_ALPHA);

以下是我要找的结果。

enter image description here

现在唯一的事情是我所拥有的透明图像中的透明图像会被忽略,这是有道理的,因为我认为目标alpha是1.为什么One minus源会添加灰色?

4 个答案:

答案 0 :(得分:11)

我想出了如何修复它。

我改变了

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

GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);

事实证明,当你加载它时,Android会预先乘以PNG图像纹理的alpha值(使白色变为灰色)。

我添加了

vColor.r = vColor.r * vColor.a;
vColor.g = vColor.g * vColor.a;
vColor.b = vColor.b * vColor.a;

到我的顶点着色器,为我的其他颜色进行相乘。

答案 1 :(得分:1)

您确定自己的内容是否正确?如果您不希望圆圈产生任何黑色,则图像中的颜色值应为完全白色,并且Alpha通道应定义圆形的形状。现在看起来图像有一个白色圆圈,alpha通道和颜色值渐渐变为零,从而产生晕圈。

答案 2 :(得分:0)

您使用的是线性采样吗?我的想法可能是如果你有一个非常小的图像(尺寸小于30-40像素),你可能会得到圆圈内部(alpha = 1)到圆圈外部的插值alpha值(alpha = 0)。这会给你中间的alpha值,导致模糊效果。

当您拥有圆形纹理时,请尝试以下代码:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

也许你可以托管你正在使用的实际纹理,以便我们可以检查它?如果这没有帮助,请发布您的绘图代码。

答案 3 :(得分:0)

您还可以除以alpha,因为问题是,当您导出纹理时,图像处理软件可能会预先乘以Alpha通道。我最终将alpha分割成了我的片段着色器。以下代码是HLSL,但您可以轻松地将其转换为GLSL:

float4 main(float4 tc: TEXCOORD0): COLOR0
{
    float4 ts = tex2D(Tex0,tc);

    //Divide out this pre-multiplied alpha
    float3 outColor = ts.rgb / ts.a;

    return float4(outColor, ts.a);
}

请注意,此操作是有损的,非常有损的,即使在这些情况下很可能就足够了,它也不是一般解决方案。在您的情况下,您可以完全忽略COLOR并在片段着色器中提供原始的alpha和white,例如return float4(1,1,1,ts.a);(转换为GLSL)