5

我正在开发一款适用于 Android 的游戏,我想知道为什么每当我绘制透明图像时,透明部分似乎总是添加一些黑色。这一切都发生了,让我的一些效果看起来很奇怪。

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

在此处输入图像描述

我在用

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

这是我正在寻找的结果。

在此处输入图像描述

现在唯一的事情是我拥有的透明黑色的透明图像被忽略了,这是有道理的,因为我认为目标 alpha 是 1。为什么一个减源会添加那个灰色?

4

4 回答 4

12

我想出了如何解决它。

我变了

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;

到我的顶点着色器为我的其他颜色做乘法。

于 2012-04-30T02:31:19.670 回答
1

你确定你的内容是正确的吗?如果您不希望圆圈产生任何黑色,则图像中的颜色值应该是完全白色的,并且 Alpha 通道应该定义圆圈的形状。现在看起来图像有一个带有 alpha 通道的白色圆圈,颜色值逐渐变为零,这会导致光晕。

于 2012-04-29T18:13:39.377 回答
0

您是否使用线性采样?我的想法可能是,如果您的图像非常小(尺寸小于 30-40 像素),您可能会在圆内部(alpha = 1)和圆外部(alpha = 0)。这将为您提供导致那种模糊效果的中间 alpha 值。

当您绑定了圆形纹理时,请尝试以下代码:

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

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

于 2012-04-29T22:10:48.073 回答
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);
}

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

于 2013-05-21T00:54:29.483 回答