OpenGL 正背面剔除和深度測試的理解

正背面剔除的理解和解決方案:

  • 在渲染過程中可能會產(chǎn)生以下這個問題:

QQ20200709-141648-HD.gif

問題:為什么會產(chǎn)生像圖片那樣的問題芳绩,會出現(xiàn)一大坨黑色的掀亥,我明明只是渲染的紅色的,黑色的是怎么來的妥色?帶著這個問題我們往下看...

  • 隱藏面消除(Hidden surface elimination)

    在繪制3D場景的時候搪花,我們需要決定哪些部分是對觀察者可見的,或者是哪些部分是對觀察者不可見的嘹害。對于不可見的部分撮竿,應(yīng)該及早丟棄。例如在一個不透明的墻壁后吼拥,就不應(yīng)該渲染倚聚,這種情況叫做“隱藏面消除“(Hidden surface elimination)
    圖中的圓圈剛開始是紅色的凿可,當我們轉(zhuǎn)動圓圈的時候惑折,就會有一部分黑色的授账,這部分黑色的就是隱藏面,是觀察者不可見的惨驶,這部分既然不可見白热,我們就不應(yīng)該把它渲染出來,接下來我們就通過隱藏面消除來優(yōu)化它粗卜。

對于這個問題屋确,我們先來看有幾種解決方案:

  • 油畫算法
    1.先繪制場景中的離觀察者較遠的物體,再繪制較近的物體.
    2.例如下?面的圖例: 先繪制紅?色部分,再繪制黃色部分,最后再繪制灰色部分,即可解決隱藏面消除的 問題
    image.png

    3.使用油畫算法的弊端,只要將場景按照物理理距離觀察者的距離遠近排序,由遠及近的繪制即可.那么會出現(xiàn) 什么問題? 如果三個三角形是疊加的情況,油畫算法將?法處理理.
    image.png

通過上面的分析,油畫算法不能處理疊加的情況续扔,那我們接下來就研究一下正背面剔除(Face Culling)攻臀。

  • 嘗試相信一個3D圖形,你從任何一個?向去觀察,最多可以看到幾個?面? 答案是,最多3面. 從一個立方體的任意位置和方向上看,你不可能看到多于3個面. 那么思考? 我們?yōu)楹我嘤嗟娜ダL制那根本看不到的3個面? 如果我們能以某種方式去丟棄這部分數(shù)據(jù),OpenGL 在渲染的性能即可提高超過50%。
  • 如何知道某個面在觀察者的視??中不會出現(xiàn)? 任何平面都有2個面,正面/背面.意味著你?個時刻只能看到一面纱昧。OpenGL 可以做到檢查所有正面朝向觀察者的面,并渲染它們.從而丟棄背面朝向的面. 這樣可以 節(jié)約片元著?器的性能刨啸。如果告訴OpenGL 你繪制的圖形,哪個面是正面,哪個面是背面,通過分析頂點數(shù)據(jù)的順序识脆。

正背面區(qū)分

  • 正面: 按照逆時針頂點連接順序的三角形面
  • 背面: 按照順時針頂點連接順序的三角形面


    image.png

分析立方體中的正背面

  • 左側(cè)三角形頂點順序為: 1—> 2—> 3 ; 右側(cè)三角形的頂點順序為: 1—> 2—> 3.
  • 當觀察者在右側(cè)時,則右邊的三角形方向為逆時針方向則為正面,?左側(cè)的三角形為順時針則為背面
  • 當觀察者在左側(cè)時,則左邊的三角形為逆時針方向判定為正面,而右側(cè)的三角形為順時針判定為背面
  • 正面和背面是有三角形的頂點定義順序和觀察者方向共同決定的.隨著觀察者的角度方向的改變,正面背面也 會跟著改變
  1. 開啟表面剔除(默認背面剔除) void glEnable(GL_CULL_FACE);
  2. 關(guān)閉表面剔除(默認背面剔除) void glDisable(GL_CULL_FACE);
  3. ?戶選擇剔除那個面(正面/背面) void glCullFace(GLenum mode);
    mode參數(shù)為:GL_FRONT,GL_BACK,GL_FRONT_AND_BACK ,默認GL_BACK
  4. ?戶指定繞序那個為正面 void glFrontFace(GLenum mode); mode參數(shù)為: GL_CW,GL_CCW,默認值:GL_CCW
  5. 例如,剔除正面實現(xiàn)(1) glCullFace(GL_BACK); glFrontFace(GL_CW);
  6. 例如,剔除正面實現(xiàn)(2) glCullFace(GL_FRONT);

深度測試

  • 概念:深度緩沖區(qū)(DepthBuffer)和顏色緩存區(qū)(ColorBuffer)是對應(yīng)的.顏?緩存區(qū)存儲像素的顏色信 息,?深度緩沖區(qū)存儲像素的深度信息. 在決定是否繪制一個物體表面時, ?先要將表面對應(yīng)的像 素的深度值與當前深度緩沖區(qū)中的值進行?較. 如果大于深度緩沖區(qū)中的值,則丟棄這部分.否則 利用這個像素對應(yīng)的深度值和顏色值.分別更新深度緩沖區(qū)和顏色緩存區(qū). 這個過程稱為”深度測試”设联。
  1. 什么是深度?
    深度其實就是該像素點在3D世界中距離攝像機的距離,Z值.
  2. 什么是深度緩沖區(qū)?
    深度緩存區(qū),就是一塊內(nèi)存區(qū)域,專門存儲著每個像素點(繪制在屏幕上的)深度值.深度值(Z值)越大, 則離攝像機就越遠.
  3. 為什么需要深度緩沖區(qū)?
    在不使?深度測試的時候,如果我們先繪制一個距離比較近的物體,再繪制距離較遠的物體,則距離遠的位圖因為后繪制,會把距離近的物體覆蓋掉. 有了深度緩沖區(qū)后,繪制物體的順序就不那么??重要的. 實際上,只要存在深度緩沖區(qū),OpenGL 都會把像素的深度值寫入到緩沖區(qū)中. 除非調(diào)用 glDepthMask(GL_FALSE)來禁止寫入.
  • 深度值計算

    • 深度值一般由16位,24位或者32位值表示灼捂,通常是24位离例。位數(shù)越高的話,深度的精確度越好悉稠。深度值的范圍在[0,1]之間宫蛆,值越小表示越靠近觀察者,值越大表示遠離觀察者偎球。
  • 深度緩沖主要是通過計算深度值來比較?小洒扎,在深度緩沖區(qū)中包含深度值介于0.0和1.0之間, 從觀察者看到其內(nèi)容與場景中的所有對象的 z 值進行了?較衰絮。這些視圖空間中的 z 值可以在投影平頭截體的近平面和遠平面之間的任何值袍冷。我們因此需要一些方法來轉(zhuǎn)換這些視圖空間 z 值 到 [0,1] 的范圍內(nèi)猫牡。

  • 使用深度測試

    • 深度緩沖區(qū),一般由窗口管理系統(tǒng),GLFW創(chuàng)建.
    • 開啟深度測試 glEnable(GL_DEPTH_TEST);
    • 在繪制場景前,清除顏色緩存區(qū),深度緩沖 glClearColor(0.0f,0.0f,0.0f,1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    • 清除深度緩沖區(qū)默認值為1.0,表示最大的深度值,深度值的范圍為(0,1)之間. 值越小表示越靠近觀察者,值越大表示 越遠離觀察者
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末胡诗,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子淌友,更是在濱河造成了極大的恐慌煌恢,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件震庭,死亡現(xiàn)場離奇詭異瑰抵,居然都是意外死亡,警方通過查閱死者的電腦和手機器联,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門二汛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來婿崭,“玉大人,你說我怎么就攤上這事肴颊∶フ唬” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵婿着,是天一觀的道長授瘦。 經(jīng)常有香客問我,道長竟宋,這世上最難降的妖魔是什么提完? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮袜硫,結(jié)果婚禮上氯葬,老公的妹妹穿的比我還像新娘挡篓。我一直安慰自己婉陷,他們只是感情好,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布官研。 她就那樣靜靜地躺著秽澳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪戏羽。 梳的紋絲不亂的頭發(fā)上担神,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機與錄音始花,去河邊找鬼妄讯。 笑死,一個胖子當著我的面吹牛酷宵,可吹牛的內(nèi)容都是我干的亥贸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼浇垦,長吁一口氣:“原來是場噩夢啊……” “哼炕置!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起男韧,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤朴摊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后此虑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體甚纲,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年朦前,在試婚紗的時候發(fā)現(xiàn)自己被綠了介杆。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片讹弯。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖这溅,靈堂內(nèi)的尸體忽然破棺而出组民,到底是詐尸還是另有隱情,我是刑警寧澤悲靴,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布臭胜,位于F島的核電站,受9級特大地震影響癞尚,放射性物質(zhì)發(fā)生泄漏耸三。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一浇揩、第九天 我趴在偏房一處隱蔽的房頂上張望仪壮。 院中可真熱鬧,春花似錦胳徽、人聲如沸积锅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽缚陷。三九已至,卻和暖如春往核,著一層夾襖步出監(jiān)牢的瞬間箫爷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工聂儒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留虎锚,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓衩婚,卻偏偏與公主長得像窜护,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子谅猾,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354