Part12 混合

        所謂的混合就是將兩種圖元的顏色按照某種規則混合產生一種新的顏色的效果。在OpenGL當中可以看到表示一個頂點的顏色我們使用的是一種稱之爲RGBA的顏色表示方案,在這種顏色表示方案當中前面三個分量RGB與通常使用的顏色表示方案相同,而最後一個分量稱之爲alpha分量。alpha這個單詞在photoshop等等的圖形設計軟件當中經常可以看到,在OpenGL當中alpha這個單詞的解釋與這些設計軟件當中的解釋幾乎完全相同,即alpha指的是圖元的不透明度,所謂的不透明度就是說如果alpha的值爲0.5那麼有一半的光可以透過圖元射到後面與之重合的圖元當中。
        在沒有使用混合之前的OpenGL程序當中往往使用3個分量的顏色函數來表示頂點的顏色,這種3個分量的顏色表示實際上是將頂點顏色的alpha值設置爲1,也就是完全不透明。而事實上在使用混合之前各個定點顏色RGBA值當中的alpha值實際上是完全沒有用處的。但是在混合當中就需要用的alpha值了。
        在混合當中原本存在於幀緩存當中的當前像素的RGBA值稱之爲目標顏色,而要繪製到幀緩存當中片元對應像素的RGBA值稱爲源顏色。在使用混合之前,如果繪製一個片元OpenGL要做的工作實際上是比較深度緩存當中這個像素的深度與要繪製進來片元對應像素的深度,如果要繪製進來的像素在幀緩存像素之前,那麼繪製新的像素,並且更新深度緩存當中的值。而使用混合以後(通常意義上使用混合就需要關閉深度緩存,這樣需要注意的是繪製片元的順序總是從裏面到外面)OpenGL要做的工作就是根據已經提供的混合函數以及源顏色和目標顏色計算新的混合顏色並且保存到幀緩存當中去。計算新顏色的公式如下:
R = Rs × Ds op Rd × Dd 
G = Gs × Ds op Gd × Dd 
B = Bs × Ds op Bd × Dd 
A = As × Ds op Ad × Ad 
這裏可以看到兩個參數Ds和Dd,這兩個參數就是我們設置的一個混合函數,通常設置混合函數我們調用OpenGL函數glBlendFunc來實現,這個函數需要兩個參數分別表示Ds和Dd兩個的值。舉個例子,假如說在一個物體之前有一塊有色的半透明的玻璃,那麼因爲深度緩存關閉的原因我們需要先繪製物體,然後繪製玻璃,假設說玻璃是藍色的,由於是半透明的那麼他的RGBA值就是(0,0,1,0.5),爲了達到玻璃的半透明效果,我們就要使用混合,在這個例子當中就要調用glBlendFunc(GL_SRC_ALPHA,GL_SRC_ONE_MINUES_ALPHA);
這裏兩個參數的意義是:
GL_SRC_ALPHA:D = As   也就是說使用源顏色的各個分量乘以源顏色的ALPHA值
GL_SRC_ONE_MINUS_ALPHA:Dd = 1-As 用目標顏色乘以源顏色ALPHA值與1的值
這樣得到的顏色正好是符合半透明的實際效果,至於混合函數其他參數的意義可以參考MSDN的說明。
        另外我們可以看到混合方程當中還有一個操作符op,這個操作符在默認情況下爲+,但是我們可以通過函數glBlendEquation來改變它。
        所以通過上面的說明我們可以總結出使用混合的方法是
1.關閉深度測試,打開混合(glEnable(GL_BLEND)),設置混合函數(glBlendFunc)
2.從裏到外依次繪製片元
        上面所講到的混合方法在場景當中所有物體的深度順序較爲簡單和有順序時比較有效,但是如果說場景當中模型的深度很複雜,並且有些物體是不透明的會完全遮擋住後面的物體,而有些物體是透明的需要使用混合時,如果還是用上面的辦法來處理就比較複雜並且容易出錯了。在這種情況下一般採用這樣一種解決方案,首先繪製不透明物體,然後再繪製那些透明的需要混合處理的物體,並且即使在繪製這些需要混合處理的物體時也不關閉深度緩存,而只是將深度緩存設置爲不可寫(用glDepthMask(FALSE)函數調用來實現),這樣的話如果繪製片元時OpenGL發現其靠近眼座標的位置上有不透明物體那麼就不繪製透明物體,否則就是用混合方式來繪製透明物體。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章