2012-04-29 24 views
4

我正在爲Android的遊戲工作,我想知道爲什麼每當我用透明度繪製圖像時,總會有一些黑色添加到透明部分。這一切都發生,使我的一些效果看起來很奇怪。OpenGL透明圖像在其中有黑色

這裏是一個例子。這兩個圓圈只是帶有模糊的白色圖像,但您可以看到一個圖像與另一個圖像重疊時是否有陰影。如果我重疊兩個圈子在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.爲什麼會一個減源添加灰色?

+0

關於編輯中的問題,你是不正確的,那是不可能的。 – Tim

+0

個人而言,我認爲這個影子看起來很棒。但那只是我。 – ashes999

回答

9

我想出瞭如何解決它。

我改變

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; 

到我的頂點着色器做乘法我的其他顏色。

+0

你可以將alpha分開。閱讀下面的評論 –

1

您確定自己的內容是否正確?如果您不希望圓圈產生任何黑色,則圖像中的顏色值應該完全是白色,alpha通道應該定義圓圈的形狀。現在,它看起來像圖像有一個白色圓圈與阿爾法通道和顏色值衰落爲零,這導致暈。

+0

是的,我的圖像是完全白色的,模糊和形狀是由alpha通道定義的。 – EmbMicro

+1

這是,但你使用什麼庫?它肯定會預先倍增你的alpha –

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

也許你可以承載您使用,使得我們可以檢查它實際的質感?如果這不起作用,請張貼您的圖紙代碼。

+0

我不認爲你理解。我想模糊,它是在原始圖像。原來不是它的黑色部分重疊。我會在問題中發表原文。 – EmbMicro

+0

@EmbMicro哦,對不起,我誤解了。如果您正在使用深度測試,您最初繪製的原始圖像中的哪一個圓圈,以及您的深度緩衝區設置是什麼樣的? – Tim

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)