什么叫做場景優(yōu)化?
每一位游戲玩家蟹倾,無論是傳統(tǒng)的 PC 和主機游戲匣缘,還是時新的手游以至 VR 游戲,都會對這樣一個名詞有著特殊的理解和關(guān)注鲜棠,那就是 FPS(幀速率肌厨,F(xiàn)rames Per Second)。FPS 太低的話豁陆,畫面就一卡一卡的柑爸,玩起來不舒服;如果是戴上 VR 頭盔的話盒音,因為暈動癥的影響表鳍,玩家甚至會迅速感到頭暈和惡心,一天都無法心情舒暢里逆。
FPS 顧名思義就是每秒鐘渲染的幀數(shù)进胯,也就是說,顯卡和顯示器每秒鐘都會更新數(shù)十張不同的圖像(幀)原押,進而形成一種動畫的效果胁镐。
從傳統(tǒng)動畫的角度上來說,每秒 10 幀以上的畫面就可以形成連續(xù)的動畫效果(例如中國古代的走馬燈),而不需要任何交互的電影放映盯漂,則采用每秒 25 幀或者接近 30 幀的播放速度颇玷,讓觀看者自在地欣賞大片。
但是加入了交互元素之后就缆,例如可以快速轉(zhuǎn)動視角的鼠標帖渠,手柄,以及 VR 頭盔竭宰,人們對于幀速率的需求就直線上升了——如果是面對平面液晶顯示屏的話空郊,受限于 IPS 屏幕本身的刷新率特性,內(nèi)容本身通常需要達到 60FPS 的渲染速度切揭;而戴上 VR 頭盔之后狞甚,采用 OLED 屏幕的內(nèi)容則可以達到 75FPS 的更新,事實上廓旬,出于盡量避免暈眩的考慮哼审,游戲內(nèi)容的畫面刷新也必須達到這個數(shù)值。
然而這談何容易:交互游戲并不是預(yù)先拍攝好的電影和動畫片孕豹。它需要根據(jù)玩家的操作來觸發(fā)不同的邏輯涩盾,并渲染出不同的畫面內(nèi)容。而游戲場景可能是復(fù)雜的励背,細碎的春霍,并且有很高的真實感和特效方面的要求——而這一切都必須在短短的1/75秒內(nèi)完成!就算顯示硬件的水準逐年提升椅野,這依然是一個極具挑戰(zhàn)性的話題:如何優(yōu)化我們的場景和渲染策略终畅,在如此有限的時間要求內(nèi),實現(xiàn)高效與細節(jié)并存的游戲內(nèi)容呢竟闪?
本文將針對這一話題做適當?shù)挠懻摾敫#欢掝}本身的技術(shù)含量已是深不見底,所以文章也只能淺嘗輒止炼蛤,只期望為讀者和同行們小啟一扇門扉妖爷。
渲染批次,扼住命運的咽喉
在描述一些晦澀難懂的名詞之前理朋,我們不妨先來看一個例子:
假設(shè)我們有一個果園絮识,每天它都要派出一輛卡車,走固定的路線運送水果到市里去嗽上。如果運送的水果總量為 10 噸次舌,而這輛卡車一次能夠承載 200 千克水果的話,那么顯而易見它需要跑上 50 趟才能完成這一任務(wù)兽愤,也許這會花費整整一天的時間才能夠完成彼念。
顯而易見挪圾,我們并不希望這項工作花掉那么多的寶貴時間,那么一種直截了當?shù)慕鉀Q方案是:給這輛卡車換上更為給力的發(fā)動機逐沙,比如 NVIDIA 的戰(zhàn)術(shù)核顯卡哲思,讓它跑全程的速度減半再減半,同樣 50 趟的任務(wù)吩案,這回只要一個上午就可以搞定了棚赔。
當然生活也許并不總是那么如意的,也許果園的工作人員早就心懷怨氣徘郭,每次給卡車只裝了 50 千克水果靠益,于是可憐的司機就需要走上足足 200 個來回,直到別人吃上早飯了還垂死地奔波在路上……
幸好崎岂,拯救他的方法也不止一種捆毫,比如,裝上戰(zhàn)術(shù)核顯卡之后冲甘,他至少能夠和別人一樣每天拉完 50 趟再按時回家吃飯了。
但是一個智商正常的果園老板應(yīng)該不會把這當成是最合理的決策吧……難道不應(yīng)該先開除那個裝貨的途样?讓爺?shù)男】ㄜ噭e這么傻兮兮地跑上 200 個批次嗎江醇?
結(jié)束我們的遐想,而現(xiàn)實卻也許傻得有些可愛:當作為內(nèi)容開發(fā)者的我們同樣遇到了“卡車花在路上的時間太長”這種問題的時候何暇,第一選擇往往是換用更逆天的顯卡和系統(tǒng)陶夜,而不是好好琢磨一下該死的工作人員藏哪兒了。
沒錯裆站,送了 200 趟水果的卡車条辟,就好比跑了 200 個渲染批次(Draw Call)的顯卡,而每個批次的執(zhí)行都是會消耗固定時間的宏胯。而為了縮短這一時間羽嫡,進而提升幀速率的開發(fā)者們,與其直接買入更新的顯示設(shè)備肩袍,倒不如先坐下來仔細想一想杭棵,渲染批次過多的瓶頸是什么(那個作孽的裝貨工?)氛赐,我又能把它優(yōu)化到什么地步(至少恢復(fù)到 50 個批次的正常水準魂爪?)。而這成百上千噸的水果就好比是復(fù)雜和精致的VR場景內(nèi)容艰管,同一時間內(nèi)能夠送達的越多滓侍,它能夠表達的內(nèi)容真實感與細節(jié)程度也就越詳實。
渲染批次(Draw Call)在以往并不是一個被十分重視的概念牲芋,制作游戲場景的美術(shù)人員更愿意用“三角面數(shù)”(Triangle Face)來描述內(nèi)容的復(fù)雜程度或者制作水準撩笆,譬如:這是一個足有 1000 萬面的卡通少女(她的每一根毛發(fā)也許都清晰可辨)尔破,又或者這是一個只有 100 萬面的故宮實景模型(然而我的高超技巧讓這一藝術(shù)瑰寶依然栩栩如生)。
殊不知浇衬,對于實時渲染而言懒构,三角面數(shù)并不足以決定渲染的效率以及幀速率結(jié)果。僅用了一個批次就完成渲染的 1000 萬面模型耘擂,和用了 1 萬個批次才渲染完成的 100 萬面模型胆剧,其執(zhí)行效率恐怕是天壤之別。后者在實際執(zhí)行當中的表現(xiàn)醉冤,恐怕一定會讓那些自信于低面數(shù)模型的人們大跌眼鏡秩霍。
然而這就引起了另一個有趣的論題:為什么會有大量的 Draw Call 呢?既然每一位開發(fā)者都能明白這樣的道理蚁阳,為什么不一開始就設(shè)計成一次 Draw Call 執(zhí)行全部場景物體的渲染操作呢铃绒?就算是因為承載力的問題不得不分成多個 Draw Call,這種簡單粗暴的設(shè)計依然應(yīng)當是最優(yōu)的解法無疑吧螺捐?
然而這樣的愿望往往無力成為現(xiàn)實颠悬,因為現(xiàn)代圖形渲染底層接口對于 Draw Call 的實際執(zhí)行,是在繪制實際幾何體圖元(Draw Primitive)的階段定血;而每次繪制圖元的操作之前赔癌,我們只能為這組圖元(可能是 200 個三角面,也可能是 10 萬個三角面)設(shè)置一張紋理圖像(Texture)澜沟,以及一組著色器(Shader)——而這兩者正是虛擬現(xiàn)實和游戲應(yīng)用當中用于表達物體材質(zhì)和真實感的最核心組件灾票。一張圖像能夠容納和清晰地表達一個精致美女的肌膚茫虽,秀發(fā),慧眼正什,紅唇埠忘,絲衣莹妒,高跟鞋旨怠,LV包蜈块,以及其他種種細致入微的內(nèi)容嗎?當然不能蜓席。所以我們也沒有辦法在一個渲染批次里搞定美女模型的一切厨内。
而與此相關(guān)的另一個問題也會困擾著更深層次的圖形開發(fā)者:場景內(nèi)容的管理雏胃。例如一座數(shù)字化的虛擬城市志鞍,每一棟樓,每一個房間统翩,每一輛車玻孟,每一位居民黍翎,都應(yīng)當是獨立存在的個體艳丛,對這些模型資源的管理也顯然應(yīng)當按照相似的分類方法氮双。然而從渲染的角度來說戴差,這樣產(chǎn)生的 Draw Call 恐怕遠遠不是最優(yōu)的選擇袭厂,甚至輕而易舉就會讓前文中送水果的卡車司機崩潰掉纹磺。
如果按照材質(zhì)把模型重新分組和整合橄杨,倒是可以進一步提升渲染的效率,不過資源的管理工作卻無疑會讓人崩潰乡摹。試想一下采转,在公安局的戶口本上聪廉,你不再屬于某個家庭氏义,而你身體的各部分則分別隸屬于短發(fā)組,麻臉組惯悠,格子衫組邻邮,灰褲子組……這種“按材質(zhì)分組”的行為看起來多少有點“漢尼拔”似的驚悚氣氛了克婶。
然而筒严,場景優(yōu)化面臨的麻煩還遠沒有盡頭。
有關(guān)填充率的那些傳說
試想一位畫家情萤,揮毫潑墨,將現(xiàn)實中的山水人物躍然紙上,描繪得栩栩如生睁宰。這些山水人物原本是自然存在的孝赫,繪制到紙上红符,就成了油彩,湊近去看,就會有濃重的顆粒感——雖然大多數(shù)情況下這并不妨礙我們觀瞻就是了雌桑。
現(xiàn)代計算機的圖形渲染過程與此類同喇喉。把復(fù)雜的場景模型躍然于屏幕之上,這一過程稱作光柵化(Rasterization)校坑,而屏幕上的像素點拣技,近看起來同樣存在顆粒感千诬,低分辨率的屏幕則更為明顯。這種顆粒感對于VR類的內(nèi)容來說更為顯著(因為 VR 眼鏡相當于放大了屏幕分辨率對畫面質(zhì)量的影響)膏斤,而它也是破壞場景真實感和效果的主因之一徐绑。
那好辦啊,有人可能會說莫辨,那就拼命增加屏幕分辨率不就好了傲茄。從現(xiàn)在的 1080p,到 2K沮榜,到 4K盘榨,到 8K……總會有徹底解決這個問題的一天吧?
然而事情并沒有這么簡單蟆融,還是回過頭來談?wù)勎覀兊漠嫾遥涸谝粡?A4 紙上畫簡筆畫草巡,也許他只需要 1-2 分鐘而已;如果是 10 米長卷型酥,那么也許要一天的時間山憨;如果是在萬里長城上……那么畫家可能直接就跳下去了,搞這么一輩子的工程弥喉,生不如死啊郁竟。
沒錯,這里的畫卷可以類比為我們所說的屏幕分辨率由境,而畫家求死的原因棚亩,只因為要畫的東西太多,而他對畫卷內(nèi)容的填充率(Fill Rate)太低了虏杰,因而渲染效率也變得慘不忍睹蔑舞。
這個問題的解決方案,無非三種嘹屯,弊端也是一目了然:
1、改用小點的畫卷(降低屏幕分辨率和用戶體驗)从撼;
2州弟、換個瘋狂的畫家(升級硬件,提升填充率)低零;
3婆翔、少畫點花里胡哨的東西(降低渲染內(nèi)容的質(zhì)量)。
聽起來都不是什么一勞永逸的選擇掏婶,并且大多數(shù)開發(fā)者一定會選用最直接的那個方案啃奴,沒錯,換更瘋狂的畫家雄妥,搞硬件的軍備競賽最蕾。
不過從場景優(yōu)化的角度來說依溯,方案三反而成了最靠譜的一條道路,并且這給各路算法豪俠和數(shù)學家們也提出了一個有趣的命題:如何在渲染質(zhì)量還看得過去的前提下瘟则,盡量少畫點“對用戶沒用”的內(nèi)容呢黎炉?
對這句話的詳細解釋就是:用戶看不到的場景不要畫出來,把它提前裁減掉(Culling)醋拧;而用戶可能本來也看不清的場景慷嗜,就用更低的細節(jié)程度(Level of Details)把它畫出來。
這里必須要解釋一句丹壕。顯卡并不是多么聰明的一種硬件產(chǎn)品庆械,它并不能主動分辨出當前提交的渲染指令中,包含的信息是否真的能夠被顯示到屏幕之上菌赖;而是選擇了另一種更為簡單的策略:不管有多少東西都先畫上去缭乘,如果不幸沒畫到紙上的話……反正你也不在乎對不對?畢竟最終用戶關(guān)注的只有紙面上的內(nèi)容而已盏袄。
然而古今中外忿峻,那些為了優(yōu)化場景而苦思冥想的開發(fā)者們,卻僅為了這一個目標前赴后繼辕羽,傷痕累累逛尚。
當然,這里所說到的“填充率”一詞刁愿,只是相關(guān)圖形系統(tǒng)運行機制的冰山一角绰寞。它還可能被進一步細分為像素填充率(光柵化操作和屏幕緩存繪制的速率)和紋理填充率(紋理在模型表面映射和采樣操作的速率)。而實際執(zhí)行過程中铣口,還可能受到顯存帶寬(顯卡在單位時間能夠傳輸數(shù)據(jù)的總量)參數(shù)的影響滤钱,而這些信息往往都會標識在具體顯卡品牌的性能說明文檔中,作為發(fā)燒友比較和購買的依據(jù)(雖然它們實際上并無統(tǒng)一標準可言)脑题。
不過這并非本文所要繼續(xù)深入闡述的命題了件缸,我們關(guān)心的,還是那些圖形學和 VR 領(lǐng)域的先行者們叔遂,為了哪怕一點點的優(yōu)化效果做出過的努力他炊。
聯(lián)系方式:0755-81699111
課程網(wǎng)址: http://www.vrkuo.com/course/vr.html