正背面剔除
-
OpenGL 規(guī)定:
- 頂點序 逆時針 = 正面
- 頂點序 順時針 = 背面
圖中立方體虹统,1234面 為逆時針 = 正面弓坞,5678面 為順時針 = 背面隧甚,OpenGL 以此為依據(jù),只需要畫正面渡冻,不需要畫背面戚扳,起到 避免畫錯/節(jié)約性能 (50%左右) 的效果,稱為 正背面剔除族吻。
-
OpenGL 默認(rèn)關(guān)閉正背面剔除帽借,需要手動打開,用完建議恢復(fù)原狀呼奢。
操作 代碼 打開正背面剔除 glEnable(GL_CULL_FACE); 關(guān)閉正背面剔除 (默認(rèn)) glDisable(GL_CULL_FACE); -
正背面剔除 在部分情況解決了 該畫哪個面宜雀、不該畫哪個面 的問題。
深度測試
圖中的觀察角度,理應(yīng)只能看到橘色怔匣,看不到綠色换怖;但計算機(jī)不那么聰明,就算我們開啟了 正背面剔除定枷,這兩個面都是正面呀孤澎,計算機(jī)有可能顯示綠色!
-
例如:下圖已開啟了 正背面剔除欠窒,但后面的畫面遮擋住前面的覆旭。
深度:物體在規(guī)范化坐標(biāo)系中的 Z值;Z值越大岖妄,則往屏幕里越深越遠(yuǎn)型将。
顏色緩沖區(qū)(ColorBuffer):存儲像素點的顏色信息。
深度緩沖區(qū) (DepthBuffer):存儲像素點的深度值荐虐。
兩個緩沖區(qū) 進(jìn)行協(xié)同工作七兜,在更新一個像素點的顏色信息前,要比較 新數(shù)據(jù)的深度值 和 深度緩沖區(qū)這個點的深度值福扬,如果新數(shù)據(jù)的深度值小腕铸,則說明它會遮擋住原來的,更新顏色信息 且 更新深度值铛碑;否則跳過狠裹。這個過程稱為 深度測試。
當(dāng)然汽烦,遮擋物如果是半透明的涛菠,要將新舊顏色進(jìn)行 顏色混合,有機(jī)會再詳細(xì)說。
-
OpenGL 默認(rèn)關(guān)閉深度測試碗暗,需要手動打開颈将,用完建議恢復(fù)原狀。
操作 代碼 打開深度測試 glEnable(GL_DEPTH_TEST); 關(guān)閉深度測試 (默認(rèn)) glDisable(GL_DEPTH_TEST); -
由此解決遮擋關(guān)系錯誤的現(xiàn)象言疗。
Z沖突 (Z-Fighting)
深度測試的核心是比較兩個數(shù)據(jù)的 Z值晴圾,在數(shù)學(xué)上看這個方法很完美,但計算機(jī)的數(shù)據(jù)精度不是無窮的:
有2個 Z值噪奄,0.5 和 0.5000000000000000000001死姚,計算機(jī)認(rèn)為他們相等,深度測試失效勤篮,稱為 Z沖突都毒。
以前玩 CS 1.5,把槍扔到地上另一把槍上碰缔,它們會重疊账劲,多個像素點出現(xiàn) Z沖突,計算機(jī)來回顯示 槍1 和 槍2金抡,造成畫面閃爍瀑焦。
-
解決方案:使重疊的像素點有 微小的、而計算機(jī)又足以識別的 Z值差梗肝,稱為 多邊形偏移榛瓮。使用有2個步驟:
-
OpenGL 默認(rèn)關(guān)閉多邊形偏移,需要手動打開巫击,用完建議恢復(fù)原狀禀晓。
操作 代碼 打開多邊形偏移 glEnable(GL_POLYGON_OFFSET_FILL); 關(guān)閉多邊形偏移 (默認(rèn)) glDisable(GL_POLYGON_OFFSET_FILL); -
設(shè)置偏移的
factor
和units
,一般都使用 -1 即可坝锰。glPolygonOffset(GLfloat factor, GLfloat units);
-
Z沖突 很少在現(xiàn)在的游戲出現(xiàn)粹懒,其解決方案未必是 多邊形偏移,而且可能有不止一種現(xiàn)代的方案什黑,有興趣可進(jìn)一步探索崎淳。