OpenGL中隱藏面消除解決方案

什么是隱藏面消除

  • 在繪制一個(gè)3D物體的時(shí)候,我們只能夠看到物體的一部分(正面),對(duì)于不可見的背面和里面,應(yīng)該不予繪制,這樣既可保證圖像顯示正確還可以提高程序性能,這種情況叫做“隱藏面消除”。


    隱藏面消除前

    隱藏面消除后

實(shí)現(xiàn)隱藏面消除的解決方案

1.油畫算法
  • 原理:
    先繪制場景中的離觀察者較遠(yuǎn)的物體,在繪制較近的物體。例如下圖中:先繪制紅色部分,在繪制黃色部分,最后在繪制灰色部分,即可解決隱藏面消除的問題。
    油畫算法
  • 弊端
    1.把不該顯示的圖像也繪制了一遍,影響性能。
    2.如果是幾個(gè)圖像互相疊加的情況下(如下圖),油畫算法將無法處理。
    圖像互相疊加
2.正背面剔除(Face Cuilling)
  • 原理:
    任何平面都有2個(gè)面,正面/背面。意味著你一個(gè)時(shí)刻只能看到一面。OPenGL 可以做到檢查所有正面朝向觀察者的面,并渲染它們。從而丟棄背面朝向的面。這樣可以節(jié)約片元著色器的性能。

問題:如何告訴OpenGL 你繪制的圖形,哪個(gè)面是正面,哪個(gè)面是背面?
答:通過分析圖形的頂點(diǎn)數(shù)據(jù)繪制順序。
正面:按照逆時(shí)針順序連接頂點(diǎn)數(shù)據(jù)。
背面:按照順時(shí)針順序連接頂點(diǎn)數(shù)據(jù)。


正背面剔除
  • 存在問題1
    當(dāng)繪制一個(gè)復(fù)雜圖形時(shí),圖形有兩個(gè)正面重疊,OPenGL 無法判斷該繪制哪一個(gè)。如下圖的圓環(huán):A面跟B面都是面向觀察者的正面,當(dāng)他們互相疊加時(shí)會(huì)出現(xiàn)問題。

  • 解決方法:開啟深度測試
    簡單來講,深度測試就是在繪制圖形的時(shí)候判斷該像素點(diǎn)的Z值(深度值),深度值越大說明離觀察者越遠(yuǎn),如果兩個(gè)正面互相疊加那么只繪制離觀察者近的那個(gè)面。
//開啟深度測試
glEnable(GL_DEPTH_TEST);

開啟深度測試后的圓環(huán):


開啟深度測試后
  • 存在問題2
    當(dāng)2個(gè)正面的深度值完全一樣時(shí),OpenGL 無法正確判斷該繪制哪一個(gè)面,深度測試結(jié)果不可預(yù)測。顯示出來的圖像會(huì)出現(xiàn)閃爍的情況,這個(gè)就是ZFighting閃爍。
    ZFighting閃爍問題
  • 解決方法:使用多邊形偏移(Polygon Offset)
    使用多邊形偏移后,如果兩個(gè)正面的深度值一樣,OpenGL 會(huì)讓它們的深度值產(chǎn)生細(xì)微的偏移,這樣就能讓2個(gè)面之間有所區(qū)分。
//開啟多邊形偏移:
glEnable(GL_POLYGON_OFFSET_FILL);
//指定偏移量
glPolygonOffset(-1,-1);

ZFighting閃爍問題預(yù)防:
1.不要將兩個(gè)物體靠得太近,避免渲染時(shí)疊在一起。
2.盡可能將近裁剪面設(shè)置的離觀察者遠(yuǎn)一點(diǎn),因?yàn)榻眉裘嫔疃鹊木_度是很高的。
3.使用更高位數(shù)的深度緩沖區(qū),通常使用的深度緩沖區(qū)是24位,現(xiàn)在有一些硬件使用32位的緩沖區(qū),使精確度得到提高。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容