混合通常是指實(shí)現(xiàn)物品的透明度的一種技術(shù)。可以理解為調(diào)色舷手,例如:紅色加藍(lán)色之后出現(xiàn)的顏色是紫色或品紅這樣的。就是兩種物品通過(guò)透明度把兩種顏色混合起來(lái)的一種技術(shù)劲绪。
一個(gè)物體的透明度是通過(guò)它顏色的aplha值來(lái)決定的男窟,Alpha顏色值是顏色向量的第四個(gè)分量盆赤。
丟棄片段
有些圖片不需要半透明,只想要一部分的時(shí)候歉眷。你就可以拋棄這部分牺六。通過(guò)alpha等于0來(lái)將其拋棄。
草的形狀和2D四邊形的形狀并不完全相同汗捡,所以你只想顯示草紋理的某些部分淑际,而忽略剩下的部分。
傳入數(shù)據(jù)到著色器凉唐,通過(guò)著色器去判斷透明度的值庸追,拋棄不需要的值。
precision mediump float;
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap; //2d紋理采樣器,默認(rèn)的激活紋理單元(0)台囱,沒(méi)有分配值
uniform sampler2D colorMap2;
void main()
{
vec4 texColor = texture2D(colorMap, varyTextCoord);
if (texColor.a < 0.1) {
discard;
}
gl_FragColor = texColor;
}
因?yàn)椴莸牡膱D像淡溯,就只有白色和綠色之分。我們把白色的部分都丟棄后簿训,就只留下綠色的部分咱娶,這樣就把草給摳圖一般扣出來(lái)。
混合
雖然直接丟棄片段很好强品,但它不能讓我們渲染半透明的圖像膘侮。我們要么渲染一個(gè)片段,要么完全丟棄它的榛。要想渲染有多個(gè)透明度級(jí)別的圖像琼了,我們需要啟用混合(Blending)。和OpenGL大多數(shù)的功能一樣夫晌,我們可以啟用GL_BLEND來(lái)啟用混合:
glEnable(GL_BLEND);
OpenGL中的混合是通過(guò)下面這個(gè)方程來(lái)實(shí)現(xiàn)的:
片段著色器運(yùn)行完成后雕薪,并且所有的測(cè)試都通過(guò)之后,這個(gè)混合方程(Blend Equation)才會(huì)應(yīng)用到片段顏色輸出與當(dāng)前顏色緩沖中的值(當(dāng)前片段之前儲(chǔ)存的之前片段的顏色)上晓淀。源顏色和目標(biāo)顏色將會(huì)由OpenGL自動(dòng)設(shè)定所袁,但源因子和目標(biāo)因子的值可以由我們來(lái)決定。我們先來(lái)看一個(gè)簡(jiǎn)單的例子:
我們有兩個(gè)方形凶掰,我們希望將這個(gè)半透明的綠色方形繪制在紅色方形之上燥爷。紅色的方形將會(huì)是目標(biāo)顏色(所以它應(yīng)該先在顏色緩沖中),我們將要在這個(gè)紅色方形之上繪制這個(gè)綠色方形懦窘。
問(wèn)題來(lái)了:我們將因子值設(shè)置為什么前翎?嘛,我們至少想讓綠色方形乘以它的alpha值畅涂,所以我們想要將Fsrc設(shè)置為源顏色向量的alpha值鱼填,也就是0.6。接下來(lái)就應(yīng)該清楚了毅戈,目標(biāo)方形的貢獻(xiàn)應(yīng)該為剩下的alpha值苹丸。如果綠色方形對(duì)最終顏色貢獻(xiàn)了60%,那么紅色方塊應(yīng)該對(duì)最終顏色貢獻(xiàn)了40%苇经,即1.0 - 0.6赘理。所以我們將Fdestination設(shè)置為1減去源顏色向量的alpha值。這個(gè)方程變成了:
結(jié)果就是重疊方形的片段包含了一個(gè)60%綠色扇单,40%紅色的一種臟兮兮的顏色:
最終的顏色將會(huì)被儲(chǔ)存到顏色緩沖中商模,替代之前的顏色。
這樣子很不錯(cuò)蜘澜,但我們?cè)撊绾巫孫penGL使用這樣的因子呢施流?正好有一個(gè)專門的函數(shù),叫做
glBlendFunc
鄙信。glBlendFunc(GLenum sfactor, GLenum dfactor)
函數(shù)接受兩個(gè)參數(shù)瞪醋,來(lái)設(shè)置源和目標(biāo)因子。OpenGL為我們定義了很多個(gè)選項(xiàng)装诡,我們將在下面列出大部分最常用的選項(xiàng)银受。為了獲得之前兩個(gè)方形的混合結(jié)果,我們需要使用源顏色向量的alpha作為源因子鸦采,使用1?alpha作為目標(biāo)因子宾巍。這將會(huì)產(chǎn)生以下的glBlendFunc:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
也可以使用glBlendFuncSeparate為RGB和alpha通道分別設(shè)置不同的選項(xiàng):
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
OpenGL甚至給了我們更多的靈活性,允許我們改變方程中源和目標(biāo)部分的運(yùn)算符渔伯。當(dāng)前源和目標(biāo)是相加的顶霞,但如果愿意的話,我們也可以讓它們相減锣吼。glBlendEquation(GLenum mode)
允許我們?cè)O(shè)置運(yùn)算符选浑,它提供了三個(gè)選項(xiàng):
通常我們都可以省略調(diào)用
glBlendEquation
,因?yàn)?code>GL_FUNC_ADD對(duì)大部分的操作來(lái)說(shuō)都是我們希望的混合方程吐限,但如果你真的想打破主流鲜侥,其它的方程也可能符合你的要求。