5

I am working on a game for Android and I was wondering why whenever I draw images with transparency there seems to always be some black added to the transparent parts. This happens all over and makes some of my effects look strange.

Here is an example. The two circles are only white images with a blur but you can see when one overlaps the other it has a shadow. If I overlap two of the circles say in Inkscape I get pure white where they overlap.

enter image description here

I am using

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

for my blending.

Any idea why this happens and how I can avoid it?

Edit: the only thing I can think of is that the two images have the same z so maybe they are blending only with the background instead of each other?

Edit: I changed

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

to

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

Here is the result I was looking for.

enter image description here

The only thing now is that the transparent images that I had that have a transparent black in them are ignored, which makes sense because I think the destination alpha is 1. Why would One minus source add that gray?

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画像のテクスチャのアルファを事前に乗算します(白が灰色に変わります)。

追加した

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

あなたの内容は正しいですか?円に黒色を生成させたくない場合は、画像の色の値を完全に白にし、アルファ チャネルで円の形状を定義する必要があります。アルファ チャネルとカラー値の両方がゼロにフェードする白い円がイメージにあるように見えます。これがハローにつながります。

于 2012-04-29T18:13:39.377 に答える
0

線形サンプリングを使用していますか? 私の考えでは、非常に小さな画像 (寸法が 30 ~ 40 ピクセル未満) がある場合、円の内側 (アルファ = 1) から円の外側 (アルファ = 0)。これにより、ぼかし効果のような中間アルファ値が得られます。

円のテクスチャがバインドされている場合は、次のコードを試してください。

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

問題は、テクスチャをエクスポートするときに、画像処理ソフトウェアがアルファ チャネルを事前に乗算する可能性があるためです。最終的に、フラグメント シェーダーにアルファ分割を行いました。次のコードは 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を完全に無視して、フラグメントシェーダーで元のアルファと白を提供できますreturn float4(1,1,1,ts.a);(GLSLに変換)

于 2013-05-21T00:54:29.483 に答える