Android OpenGL ES(二)----平滑著色,androidopengl
直線或者三角形上的每個片段混合後的顏色可以用一個varying產生。我們不僅能混合顏色,還可以給varying傳遞任何值,OpenGL會選擇屬於那條直線的兩個值,或者屬於那個三角形的三個值,並平滑地在那個基本圖元上混合這些值,每個片段都會有一個不同的值。這種混合是使用線性插值實現的。要瞭解它是怎麼工作的,讓我們首先以一條直線為例開始講解。
1.沿著一條直線做線性插值
假設有一條直線,它有一個紅色頂點和一個綠色頂點,我們要從一個向另外一個混合顏色。
在這條直線的左邊,每個片段的顏色更多地呈紅色;隨著向右邊前進,那些片段的紅色分量逐漸減少,在中間處,它們處於紅色和綠色之間;隨著與綠色頂點越來越近,片段也就變得越來越綠了。
我們可以看到每種顏色分量都隨著直線長度線性縮放。因為這條線段的左側頂點是紅色,而右側頂點是綠色,它的左端就是100%紅色,中間是50%紅色,而右端是0%的紅色。
綠色的變化也是一樣的。因為左側頂點是紅色,而右側頂點是綠色的,這個線段的左端就是0%綠色,中間是50%綠色,而右端就是100%綠色。
一旦我們把這兩個顏色疊加在一起,最終就得到一條混合後的直線。
這就是線性插值的基本解釋。每種顏色的強度依賴於每個片段與包含那個顏色的頂點的距離。
為也計算這些,我們可以用頂點0和頂點1的值計算出當前片段對應的距離比。距離比僅僅是0到100之間的百分比,0%是左邊的頂點,而100%就是右邊的頂點。當我們從左向右移動,這個距離比例也會從0%向100%線性增加。這是幾個距離比的例子:
要使用線性插值計算實際混合後的值,我們可以使用下面的公式:
Blended_value=(vertex_0_value*(100%-distance_radio))+(vertex_1_value*distance_radio)
這個計算公式是應用於每個分量的,因此,如果我們處理顏色值,這個計算就會分別應用在紅色,綠色,藍色和阿爾法分量上,計算的結果合并成一個新的顏色值。
讓我們用這條直線的例子驗證一下這個公式。設vertex_0_value為紅色,它的RGB值是(1,0,0),設vertex_1_value為綠色,它的RGB值是(0,1,0)。計算一下這條線段上幾個位置的顏色。
表4-1 線性插值公式
位置 |
距離比 |
公式 |
最左端 |
0% |
(vertex_0_value*(1-distance_radio))+(vertex_1_value*distance_radio)=((1,0,0)*(100%-0%)+(0,1,0)*0%)=((1,0,0)*100%)=(1,0,0)(紅色) |
|
直線的四分之一處 |
25% |
(vertex_0_value*(1-distance_radio))+(vertex_1_value*distance_radio)=((1,0,0)*(100%-25%)+(0,1,0)*25%)=((1,0,0)*75%)+((0,1,0)*25%)=(0.75,0,0)+(0,0.25,0)=(0.75,0.25,0)(大紅) |
中間 |
50% |
(vertex_0_value*(1-distance_radio))+(vertex_1_value*distance_radio)=((1,0,0)*(100%-50%)+(0,1,0)*50%)=((1,0,0)*50%)+((0,1,0)*50%)=(0.5,0,0)+(0,0.5,0)=(0.5,0.5,0)(半紅半綠) |
直線的四分之三處 |
75% |
(vertex_0_value*(1-distance_radio))+(vertex_1_value*distance_radio)=((1,0,0)*(100%-75%)+(0,1,0)*75%)=((1,0,0)*25%)+((0,1,0)*75%)=(0.25,0,0)+(0,0.75,0)=(0.25,0.75,0)(大綠) |
最右端 |
100% |
(vertex_0_value*(1-distance_radio))+(vertex_1_value*distance_radio)=((1,0,0)*(100%-100%)+(0,1,0)*100%)=((1,0,0)*0%)+((0,1,0)*100%)=(0,1,0)(綠色) |
要注意到,任何時候兩個顏色的權重加起來都是100%。如果紅色是100%,綠色就是0%;如果紅色是50%,那綠色就是50%。
使用一個varying,我們就可以把任何兩種顏色混合在一起。當然,這不只限於顏色;任何其他屬性也可以應用插值技術。
2.在一個三角形表面混合
當我們只處理兩個點的時候,闡明線性插值是怎麼工作的並不困難;我們知道,從某個顏色的一個頂點到另一個頂點,其比例是從100%到0%縮減,所有按比例縮減的顏色合在一起就得到了最後的顏色。
在一個三角形上的線性插值也是一樣的工作原理,但是現在需要處理三個點和三種顏色。讓我們看一個直觀的例子:
這個三角形與三種顏色有關聯:頂端頂點是青色,左端頂點是紅色,右端定點是黃色。讓我們把這個三角形按每個頂點衍生出來的顏色進行分解:
就像那條直線一樣,每個顏色在接近它的頂點處都是最強的,向其他頂點移動就會變暗。我們同樣用比例確定每種顏色的相對權重,但這次要使用的面積的比例,而不是長度。
對於這個三角形內任何給定的點,從那個點向每個頂點所對應的點畫一條直線就可以產生三個內部三角形。這三個內部三角形的面積比例決定了那個點上每種顏色的權重。比如,那個點上黃色的強度就取決黃色頂點相對的那個內部三角形的面積。距離黃色頂點越金的點,它的相對三角形越大,在那個點的片段就越黃。
與直線一樣,這些權重之和也總是等於100%。可以使用下面的公司計算三角形內任何一個點的顏色分量:
Blended_value=(vertex_0_value*vertex_0_weight)+(vertex_1_value*vertex_1_weight)+(vertex_2_value*(100%-vertex_0_weight-vertex_1_weight))
我們已經理解了它在直線上是怎麼工作的,在這種情況下,我們就不需要為此舉出具體的例子了。原理是一樣的,只是這次要處理三個點而不是兩個。
看不懂向量演算法的可以先看看線性代數,當然兩個公式相對來說很簡單。要深入學習OpenGL ES涉及到兩門課程,開始講解可能不明顯,後面的應用越來越多的時候涉及的課程的知識會越來越多。當然計算更多的是線上性代數,而後面空間的構思會涉及離散數學的圖論裡面的知識。
下一篇講解OpenGL程式的基本編程。