2015-10-20 63 views
2

我簡化了我的問題來繪製一個正方形來說明。我想繪製一個紋理,它將alpha通道從0減至255,並垂直回0,以便與背景融合。現在它使背景變暗,我找不到原因。這是使用iOS上的OpenGL ES 9.在OpenGL ES中混合不能像我認爲的那樣工作

首先,我啓用我想我要的混合:

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

然後我填的是緩衝帶綠色:

glClearColor(0, 0.5, 0, 1.0); 
glClear(GL_COLOR_BUFFER_BIT); 

我有這個像我使用的質地:

Texture

我畫以下的頂點({X,Y,Z},{R,G,B,A},{TX,TY})與GL_TRIANGLES:

{{0.4, 0.3, 0}, {1, 0, 0, 1}, {0, 0}}, 
{{0.6, 0.3, 0}, {1, 0, 0, 1}, {1, 0}}, 
{{0.4, 0.5, 0}, {1, 0, 0, 1}, {0, 1}}, 
{{0.6, 0.3, 0}, {1, 0, 0, 1}, {1, 0}}, 
{{0.4, 0.5, 0}, {1, 0, 0, 1}, {0, 1}}, 
{{0.6, 0.5, 0}, {1, 0, 0, 1}, {1, 1}}, 

我希望頂點的紅色成分,以調節質地,因爲這是我的片段着色器:

varying lowp vec4 DestinationColor; 

varying lowp vec2 TexCoordOut; 
uniform sampler2D Texture; 

void main(void) { 
    gl_FragColor = DestinationColor * texture2D(Texture, TexCoordOut); 
} 

這樣做,但結果不是簡單地在綠色紅色。天黑的邊緣,在那裏我會想到要繪製只是綠色:

Problem

的答案類似的問題here說我應該使用glTexEnv(GL_BLEND)。不過,我認爲這是一個OpenGL ES 1 API。

任何人都知道我可以如何實現所需的混合?我想讓紅色在綠色中消失。頂部和底部應該是綠色的,而不是較深的。不應該有明顯的水平邊緣。

編輯:我添加更多圖片說明我的問題。下面是GIMP兩個粉紅色圓點:

Pink dots in GIMP

當我在其他(GIMP)的頂部移動一個,他們很好地融爲一體。他們還與綠色背景很好地融合:

Pink dots in GIMP, overlayed

當我重新創建在OpenGL ES,我得到的顏色變深,這是尤其是粉紅色的圓點疊加可見。我做了一個很窄的這個時候,所以你能看到的效果更好:

Pink dots in OpenGL ES

我都嘗試glBlendFunc和glBlendFuncSeparate,這就造成同樣的效果。請注意背景alpha是1.

+0

我在混合功能上有些生疏,但是你的截圖看起來像結果類似於Photoshop的「繁殖」。我認爲你需要一個不同的混合函數,但不能完全回答哪一個... –

+0

應該有一個常用混合函數的「備忘單」,以供參考... –

+0

我到達了這個混合函數,因爲它被推薦爲「正常」。 GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA應該表示color_blended = color_src * alpha_src + color_destination *(1 - alpha_src)。這就是我困惑的原因。假設alpha是0.1,紅色是1,綠色是0.5,那些邊緣應該是0.1(1,0,0)+(1-0.1)(0,0.5,0)=(0.1,0.45,0),對?如果您打開一個顏色比較網站並將#1A7300(混合示例)與#008000(背景)進行比較,則不會太暗。 –

回答

0

您的問題很可能是顯示alpha通道本身,而不是顏色。由於您使用直接混合功能,因此它會將alpha通道設置爲低於1.0的值,然後您將其看作顯示屏上的預乘顏色值:RGB = RGB*A。您應該使用混合功能分開單獨處理alpha通道:

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE) 

現在,這將混合的顏色如你預期,但保持1.0目的地阿爾法值,你鮮明的色彩設置。

+0

這是非常有用的信息,這看起來像一個更好的混合方式。但我很遺憾地說它對我沒有任何影響。 –

+1

難道你的紋理是從圖像中加載的,所以顏色是alpha預乘?基本上同樣的事情發生在將圖像轉換爲RGBA原始數據並且顏色RGB與alpha相乘時產生陰影結果。嘗試檢查一些半透明的像素,如果RGB部分是相同的或是否縮放(它需要是相同的) –

+0

絕妙的主意!我並沒有想到紋理本身可能是錯誤的。我只是看,我正在使用(iOS常量)kCGImageAlphaPremultipliedLast將紋理繪製到內存中。我猜你幾乎可以肯定找到了我的問題的根源。我用kCGImageAlphaLast得不到任何數據,所以我會繼續努力。我很快會回來驗證這確實是解決方案。 –

0

如果您的設備使用默認設置,假設像素數據是預先多元化的,那麼您可能會得到類似於您所看到的結果。我建議將您的Alpha通道圖像轉換爲簡單的灰度圖,然後將其保存爲PNG並驗證它是灰度而不是BGRA格式。然後,以正常方式將此8位每像素數據加載到紋理中,而不必擔心任何預乘問題(灰度不包含和alpha通道)。接下來,通過讀取灰度測試中的單個字節,然後將現有的DestinationColor的3個分量乘以該線性alpha值,執行着色器中的預乘步驟。例如,這個預先倍增的步驟讓我的着色器在iOS上工作。

相關問題