2013-04-30 101 views
2

我正在寫一個基於PyOpenGL的UI來手動對齊圖像。我將兩個圖像顯示爲紋理四邊形,即靜態圖像上的移動圖像。運動圖像以不同的阿爾法表示爲紅色,即glColor4f(1.,0.,0.,overlay_opacity),並且靜態圖像以不變的不透明度等於1的青色顯示,即glColor4f(0.,1.,1.,1.)。然後用戶可以通過鼠標滾動來改變overlay_opacity,以便在移動圖像和參考圖像之間淡入。opengl:非線性加顏色混合

此刻我正在使用glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)。雖然這可以讓我在青色和紅色圖像之間平穩淡化,但這也意味着當overlay_opacity等於0.5時,我只能獲得紅色和青色圖像的最大強度的一半,所以結果看起來很暗淡和泥濘。如果我使用glBlendFunc(GL_SRC_ALPHA,GL_ONE),我總是會獲得青色圖像的最大強度,所以我無法淡出它。我真正想要的是某種非線性混合的,看起來像下面的第三個圖表:

enter image description here

我想我也許可以做到這一點的一個片段着色器,但它好像有應該是一個更簡單隻用glBlendFunc()即可達到同樣的效果。我也試過GL_SRC_ALPHA_SATURATE,這在我的實現中似乎不起作用。

+0

我只是硬着頭皮做出一個快速着色器。沒有問題,然後關於發生了什麼:) – 2013-04-30 21:51:31

+0

@MichaelDorgan:你無法控制使用着色器混合。即使在現代GPU中,混合仍然是硬件之一。 – datenwolf 2013-04-30 22:55:56

回答

2

快速回答:不,這不可能只使用OpenGL調用。 GL_SRC_ALPHA_SATURATE不應該做你想要麼,它的RGB因素是min(Asrc, (1-Adest)),你的情況是很可能最後總是等於Asrc,因爲我相信你的目的地阿爾法始終爲0

長的答案是什麼:你最好的並且唯一的選擇是編寫所述片段着色器。爲了達到你想要的東西,你必須使用一些欺騙手段。我建議用alpha因子預先乘以疊加顏色,並輸出另一個alpha值以混合目標顏色。類似這樣的公式應該足夠了:

// Note I cap off the alpha values in both cases to achieve the desired non-linear ramp 
float alpha = overlay_opacity * 2.0f; 
out = vec4(color.rgb * min(1.0f, alpha), min(1.0f, 2.0f - alpha)); 

然後用下面的混合功能,以確保目標的顏色混合,以及:

glBlendFunc(GL_ONE, GL_SRC_ALPHA); 

一個進一步的優化,你注意到我由乘疊加不透明度兩個用於限制這兩個alpha值。在將其傳遞給着色器之前,您可以預先將它乘以2,這將削減每個像素的一些乘法運算。

希望這會解決你的問題,祝你好運!

1

既然你只是混合圖像,你可以用一招:首先渲染圖像A,調製它的顏色。然後使用glBlendFunc(GL_ONE, GL_ONE)在第一個圖像上繪製第二個圖像,使其重疊並再次調整顏色。通過使後層和前層的調製色彩符合您所需的混合曲線,您可以獲得所需的色彩。