標籤:
關於透明,OpenGL/ES 中可以通過 blend (混色) 來簡單實現,混色的基本原理就是把要繪製的物體的顏色與螢幕上已經繪製好的顏色以一定比例來混合,最後的顏色看上去就像半透明一樣。
要使用混合先要通過 glEnable 函數來啟用
1 glEnable(GL10.GL_BLEND);
然後通過 glBlendFunc 來設定下要使用的混合方法
1 glBlendFunc(sfactor, dfactor);
sfactor 及 dfactor 分別代表源和目標顏色在混合時所佔比重的枚舉常量。其中 sfactor 可取值包括:GL_ZERO, GL_ONE, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA_SATURATE ; 而 dfactor 可取值包括:GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA。
以下說明及公式中所涉及顏色的R、G、B、A值都是指浮點形式,即範圍在 0.0f – 1.0f 之間。
在計算混色時,首先是根據以上的枚舉得出源顏色和目標顏色的係數,然後分別與源和目標顏色相乘(乘積大於1時取值1),然後再把得出的結果相加。那麼如果假設根據以上枚舉得出的RGBA四個成分上的係數分別為 源 sfR, sfG, sfB, sfA, 目標 dfR, dfG, dfB, dfA, 源和目標的顏色成分值分別用 sR, sG, sB, sA 和 dR, dG, dB, dA 表示的話, 最終結果色的 rR, rG, rB, rA 分別為:
rR = sR * sfR + dR * dfR
rG = sG * sfG + dG * dfG
rB = sB * sfB + dB * dfB
rA = sA * sfA + dA * dfA
以上 rR, rG, rB, rA 的值如果大於 1 則最終取值為 1 。
然後再來看看 xfR, xfG, xfB, xfA ( x => s / d )是怎麼得出來的。
factor枚舉 xfR, xfG, xfB, xfA
GL_ZERO 0, 0, 0, 0
GL_ONE 1, 1, 1, 1
GL_SRC_COLOR sR, sG, sB, sA
GL_DST_COLOR dR, dG, dB, dA
GL_ONE_MINUS_SRC_COLOR 1-sR, 1-sG, 1-sB, 1-sA
GL_ONE_MINUS_DST_COLOR 1-dR, 1-dG, 1-dB, 1-dA
GL_SRC_ALPHA sA, sA, sA, sA
GL_DST_ALPHA dA, dA, dA, dA
GL_ONE_MINUS_SRC_ALPHA 1-sA, 1-sA, 1-sA, 1-sA
GL_ONE_MINUS_DST_ALPHA 1-dA, 1-dA, 1-dA, 1-dA
GL_SRC_ALPHA_SATURATE i, i, i, 1 *
上邊的表中最後的 i 取值為 min ( sA, 1-dA )
根據以上公式,
glBlendFunc(GL_ONE, GL_ONE); 即源與目標顏色的RGBA分別相加。
glBlendFunc(GL_ONE, GL_ZERO); 即只取源顏色,這也是預設值。
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 是比較典型的半透明效果,如果源色 alpha 為0,則取目標色,如果源色alpha為1,則取源色,否則視源色的alpha大小各取一部分。源色的alpha越大,則源色取的越多,最終結果源色的表現更強;源色的alpha越小,則目標色“透過”的越多。
此外在一般的渲染過程中,都會把有半透明效果的渲染放到後邊,先把不透明的部分在深度測試啟用的情況下渲染完, 再關閉深度測試寫入(glDepthMask(false)),並渲染半透明的部分。這樣就不會出現由於半透明且離鏡頭近的面被先渲染時汙染深度緩衝了。
[ios][opengles]opengles在ios上的透明問題