OpenGL渲染技巧

OpenGL渲染技巧

了解了OpenGL的渲染流程和常用API后,就可以簡(jiǎn)單的繪制出圖形了细层。但是在繪制中可能會(huì)碰到些意想不到的問(wèn)題惜辑。

在默認(rèn)情況下,我們所渲染的每個(gè)點(diǎn)疫赎、線或三角形都會(huì)在屏幕上進(jìn)行光柵化盛撑,并且會(huì)按照在組合圖元批次時(shí)指定的順序進(jìn)行排列,這在某些情況下會(huì)產(chǎn)生問(wèn)題捧搞。其中一個(gè)可能出現(xiàn)的問(wèn)題是抵卫,如果我們繪制一個(gè)由很多個(gè)三角形組成的實(shí)體對(duì)象,那么第一個(gè)繪制的三角形可能會(huì)被后面繪制的三角形覆蓋。

1.旋轉(zhuǎn)中的圓環(huán)

圖中胎撇,圓環(huán)上有些三角形在圓環(huán)的背面介粘,而另一些則在圓環(huán)的正面。我們應(yīng)該是看不到背面的晚树。

多邊形的正面和背面

OpenGL中最簡(jiǎn)單的實(shí)體多邊形就是三角形姻采,它只有3個(gè)邊。光柵化硬件最歡迎三角形题涨,而現(xiàn)在三角形已經(jīng)是OpenGL中支持的唯一一種多邊形了偎谁。每3個(gè)頂點(diǎn)定義一個(gè)新的三角形总滩。下圖是兩個(gè)三角形,它們是用6個(gè)頂點(diǎn)進(jìn)行繪制的巡雨,這6個(gè)頂點(diǎn)編號(hào)依次為V0到V5闰渔。

2.順時(shí)針環(huán)繞

請(qǐng)注意連接頂點(diǎn)的線段上所標(biāo)示的箭頭。在繪制第一個(gè)三角形時(shí)铐望,線條將按照從V0到V1,再到V2冈涧,最后回到V0的順序來(lái)繪制一個(gè)閉合的三角形。這個(gè)路徑是按照頂點(diǎn)被指定的順序沿著順時(shí)針?lè)较虻恼埽@種方向特性也體現(xiàn)在了第二個(gè)三角形中督弓。這種順序與方向結(jié)合來(lái)指定頂點(diǎn)的方式稱(chēng)為環(huán)繞。圖中右邊的三角形就被稱(chēng)作是順時(shí)針環(huán)繞的乒验。如果我們將左邊三角形的V4和V5的位置進(jìn)行交換愚隧,我們就得到了逆時(shí)針環(huán)繞。下圖是兩個(gè)三角形锻全,它們的纏繞方向相反狂塘。

圖3

在默認(rèn)情況下,OpenGL認(rèn)為具有逆時(shí)針?lè)较颦h(huán)繞的多邊形是正面的鳄厌。這意味著圖3的左側(cè)是三角形的正面荞胡,而右側(cè)是三角形的背面。

我們常常希望為一個(gè)多邊形的正面和背面分別設(shè)置不同的物理特征了嚎。我們可以完全隱藏一個(gè)多邊形的背面泪漂,或者給它設(shè)置-種不同的顏色和反射屬性。紋理圖像在背面三角形中也是相反的歪泳。在一個(gè)場(chǎng)景中萝勤,使所有的多邊形保持環(huán)繞方向的一致,并使用正面多邊
形來(lái)繪制所有實(shí)心物體的外表面是非常重要的夹囚。

如果想改變OpenGL的這個(gè)默認(rèn)行為纵刘,可以調(diào)用下面這個(gè)函數(shù)邀窃。

/*
GL_CW:順時(shí)針環(huán)繞的多邊形將為正面
GL_CCW:逆時(shí)針環(huán)繞的多邊形將為正面
*/
g1FrontFace(GL_CW) ;

油畫(huà)法

對(duì)于這個(gè)問(wèn)題荸哟,一個(gè)可能的解決辦法是,對(duì)這些三角形進(jìn)行排序,并且首先渲染那些較遠(yuǎn)的三角形瞬捕,再在它們上方渲染那些較近的三角形鞍历。這種方式稱(chēng)為“油畫(huà)法" ( painters algorithm )。

油畫(huà)法

這種方法在計(jì)算機(jī)圖形處理中是非常低效的肪虎,主要原因有兩個(gè)劣砍。

  1. 必須對(duì)任何發(fā)生幾何圖形重疊地方每個(gè)像素進(jìn)行兩次寫(xiě)操作,而在存儲(chǔ)其中進(jìn)行寫(xiě)操作會(huì)使速度變慢扇救。
  2. 對(duì)獨(dú)立的三角形進(jìn)行排序的開(kāi)銷(xiāo)會(huì)過(guò)高刑枝。

油畫(huà)法弊端:如果三個(gè)三角形是疊加的情況香嗓,油畫(huà)法將無(wú)法處理!

正面和背面剔除

在任何情況下装畅,我們都應(yīng)該只能看到正面靠娱,看不到背面,那為何還要浪費(fèi)資源繪制背面呢掠兄?對(duì)三角形的區(qū)分正面和背面的原因之一就是為了剔除像云。背面剔除能夠極大的提高性能,并修正圖1出現(xiàn)的問(wèn)題蚂夕。這種方式是非常高效的迅诬,在渲染的圖元裝配階段就整體拋棄了一些三角形,并沒(méi)有執(zhí)行任何不恰當(dāng)?shù)墓鈻呕僮鳌?/p>

使用glEnableglDisable函數(shù)即可設(shè)置表面剔除功能婿牍。

glEnable(GL_CULL_FACE);    //開(kāi)啟
glDisable(GL_CULL_FACE) ;  //關(guān)閉

指明剔除的是正面還是背面調(diào)用函數(shù)glCullFace侈贷。

/*
mode的可選值:
GL_FRONT
GL_BACK
GL_FRONT_AND_BACK
*/
void glCullFace(GLenum mode);

表面剔除后的效果

表面剔除后的效果

深度測(cè)試

仔細(xì)觀察不難發(fā)現(xiàn)我們?cè)谶M(jìn)行表面剔除后仍然會(huì)有一些不現(xiàn)實(shí)的畫(huà)面。

就算背面剔除能夠消除位于對(duì)象背面的三角形等脂,那么如果是重疊的獨(dú)立對(duì)象又該怎么辦呢铐维?我們之前提到過(guò)油畫(huà)法,這種方法是根據(jù)一種油畫(huà)使用的技術(shù)而得名的慎菲。我們只要先簡(jiǎn)單地繪制背景嫁蛇,再在上面繪制較近的對(duì)象。這樣做可能只要在畫(huà)布上進(jìn)行次數(shù)不多的繪制( 在手工繪制時(shí)更加有用)露该,但對(duì)于圖形硬件來(lái)說(shuō)睬棚,這樣做會(huì)導(dǎo)致在同一個(gè)片段區(qū)域重復(fù)進(jìn)行繪制,而每一次繪制都會(huì)產(chǎn)生性能開(kāi)銷(xiāo)解幼。如果開(kāi)銷(xiāo)過(guò)大則導(dǎo)致光柵化過(guò)程變慢抑党,我們將這種方式稱(chēng)為“填充受限”。但是將油畫(huà)法顛倒過(guò)來(lái)使用撵摆,實(shí)際上將會(huì)加速填充性能底靠。首先繪制那些離觀察者較近的對(duì)象,然后再繪制那些較遠(yuǎn)的對(duì)象。

深度測(cè)試將消除那些應(yīng)該被已存在像素覆蓋的像素,這將節(jié)省可觀的存儲(chǔ)器帶寬特铝。

深度測(cè)試是另外一種高效消除隱藏表面的技術(shù)暑中。它的概念很簡(jiǎn)單:在繪制一 個(gè)像素時(shí),將一個(gè)值(稱(chēng)為z值)分配給它鲫剿,這個(gè)值表示它到觀察者的距離鳄逾。然后,當(dāng)另外一個(gè)像素需要在屏幕上的同樣位置進(jìn)行繪制時(shí)灵莲,新像素的z值將與已經(jīng)存儲(chǔ)的像素的z值進(jìn)行比較雕凹。如果新像素的z值比較大,那么它距離觀察者就比較近,這樣就在原來(lái)的像素上面枚抵,所以原來(lái)的像素就會(huì)被新的像素覆蓋线欲。如果新像素的z值更低,那么它
就必須位于原來(lái)像素的后面汽摹,不能遮住原來(lái)的像素询筏。在內(nèi)部,這個(gè)任務(wù)是通過(guò)深度緩沖區(qū)實(shí)現(xiàn)的,它存儲(chǔ)了屏幕上每個(gè)像素的深度值竖慧。

我們?cè)谑褂肎LUT設(shè)置OpenGL窗口的時(shí)候嫌套,應(yīng)該請(qǐng)求一個(gè)深度緩沖區(qū)并啟用深度測(cè)試。

//申請(qǐng)一個(gè)顏色緩沖區(qū)和一個(gè)深度緩沖區(qū)圾旨。
glutInitDisplayMode(GLUT_DOUBLEI_GLUT_RGBA | GLUT_DEPTH);
//啟用深度測(cè)試
glEnable(GL_DEPTH_TEST);

如果沒(méi)有深度緩沖區(qū)踱讨,那么啟用深度測(cè)試的命令將被忽略。

開(kāi)啟深度測(cè)試的效果
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末砍的,一起剝皮案震驚了整個(gè)濱河市痹筛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌廓鞠,老刑警劉巖帚稠,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異床佳,居然都是意外死亡滋早,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)砌们,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)杆麸,“玉大人,你說(shuō)我怎么就攤上這事浪感∥敉罚” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵影兽,是天一觀的道長(zhǎng)揭斧。 經(jīng)常有香客問(wèn)我,道長(zhǎng)峻堰,這世上最難降的妖魔是什么讹开? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮茧妒,結(jié)果婚禮上萧吠,老公的妹妹穿的比我還像新娘左冬。我一直安慰自己桐筏,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布拇砰。 她就那樣靜靜地躺著梅忌,像睡著了一般狰腌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上牧氮,一...
    開(kāi)封第一講書(shū)人閱讀 49,821評(píng)論 1 290
  • 那天琼腔,我揣著相機(jī)與錄音,去河邊找鬼踱葛。 笑死丹莲,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的尸诽。 我是一名探鬼主播甥材,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼性含!你這毒婦竟也來(lái)了洲赵?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤商蕴,失蹤者是張志新(化名)和其女友劉穎叠萍,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體绪商,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡苛谷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了格郁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抄腔。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖理张,靈堂內(nèi)的尸體忽然破棺而出赫蛇,到底是詐尸還是另有隱情,我是刑警寧澤雾叭,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布悟耘,位于F島的核電站,受9級(jí)特大地震影響织狐,放射性物質(zhì)發(fā)生泄漏暂幼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一移迫、第九天 我趴在偏房一處隱蔽的房頂上張望旺嬉。 院中可真熱鬧,春花似錦厨埋、人聲如沸邪媳。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)雨效。三九已至迅涮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間徽龟,已是汗流浹背叮姑。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留据悔,地道東北人传透。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像极颓,于是被迫代替她去往敵國(guó)和親旷祸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容