我正在开发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.为什么One minus源会添加灰色?
答案 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)