一.正背面剔除
//GLT_SHADER_DEFAULT_LIGHT 默認光源著色器
//模型視圖矩陣
//投影矩陣
//基本顏色
shaderManager.UseStockShader(GLT_SHADER_DEFAULT_LIGHT,transformPipeline.GetModelViewMatrix,transformPipeline.GetProjectionMatrix(),vRed);
我們在繪制3D圖形時,使用使用默認光源著色器渲染正常情況下看不出任何問題,但是經過我們旋轉后會出現圖2問題,這是為什么呢?其實這是因為在旋轉過程中,我們不應該看到的東西,它被渲染出來了,所以需要讓我們告訴它哪塊不需要被渲染。這種情況就叫做“隱藏面消除”。
在這之前,我們提到過油畫算法,油畫算法是什么?
如圖三,油畫算法通俗來講就是指,在繪制過程中,使用遠小近大的原則一層一層的繪制出圖層。
但是類似圖4的問題,我們可以通過油畫算法來解決么?答案是不能的,所以我們需要使用正背面剔除。
正背面剔除是什么?
在3D圖形中,我們如果以一個角度去觀察這個3D圖形,我們最多只能看到這個圖形的三個面,那這樣的話我們可以不去繪制背面的面,同時也可以節省片元著色器的性能。
但隨之而來的是我們怎么去判定正背面?
?在OpenGL中,是由三角形來繪制圖形的,那在3D環境中,OpenGL規定:
順時針旋轉繪制頂點的三角形是背面三角形。
逆時針旋轉繪制頂點的三角形是正面三角形。
由此我們可以知道,配合上camera 與順逆三角形就可以判定哪個是正面,哪個是背面。
所以我們開啟下面
開啟表面剔除(默認背面剔除)
void glEnable(GL_CULL_FACE);
用戶選擇剔除那個面
mode參數:GL_FRONT,GL_BACK,GL_FRONT_AND_BACK
void glCullFace(GLenum mode);
例如:
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
二.深度測試
在開啟正背面剔除后,出現了上述問題,這個問題的出現時因為我們在旋轉過程中,重疊部分,OpenGL不清楚是應該顯示哪個一塊,所以我們引入了深度測試?
深度:深度就是在OpenGL坐標系中,像素點Z坐標距離觀察者的距離。
如果觀察者在Z軸的正方向,Z值越大則靠近觀察者;
如果觀察者在Z軸的反方向,Z值越大則遠離觀察者;
所以我們可以根據哪個圖層離觀察者近,就顯示哪個。
//開啟深度測試
glEnable(GL_DEPTH_TEST);
但是同時,我們開啟深度測試后會出現Z-Fighting閃爍問題,什么是Z-Fighting閃爍?
如上圖,在深度測試緩存中,兩個圖層靠的太近的話,受限于深度的精度問題,可能會默認為兩個圖層在同一深度,這樣的話OpenGL就分不出來誰先誰后,這樣就會出現Z-Fighting閃爍。那出現這個問題后我們怎么去解決呢?
在兩個圖層中增加一個間隔即可解決Z-Fighting閃爍問題,這個方式叫做“多邊形偏移”
//啟用Polygon Offset
glEnable(GL_POLYGON_OFFSET_FILL);
三.顏色混合
對于兩個顏色混合的時候遵循如下方程式:
Cf = (Cs * S) + (Cd * D)
Cf :最終計算的顏色
Cs:源顏色(將要存入的顏色值)離觀察者近的顏色
S:源混合因子 (源alpha值?)
Cd:目標顏色(已經存入的顏色值)
D:目標混合因子 (1-源alpha值)
//開啟混合
glEnable(BL_BIEND);