我們都希望能夠在場(chǎng)景中投入一百萬個(gè)物體,不幸的是满着,渲染和管理大量的游戲?qū)ο笫且誀奚麮PU和GPU性能為代價(jià)的蟹地,因?yàn)橛刑郉raw Call的問題,最后我們必須找到其他的解決方案或悲。
在本文中孙咪,我們將討論兩種優(yōu)化技術(shù),它們可以幫助您減少Unity游戲中的Draw Call數(shù)量以提高整體性能:批處理和GPU Instancing巡语。
批處理
開發(fā)者在日常工作中遇到的最常見的問題之一是性能不足翎蹈,這是由于CPU和GPU的運(yùn)行能力不足。一些游戲可以運(yùn)行在PC上男公,但是在移動(dòng)設(shè)備上不行荤堪。游戲運(yùn)行時(shí)運(yùn)行是否流暢受Draw Call數(shù)量的影響很大。有幾個(gè)解決方案能幫助您解決這個(gè)問題理澎。最常見的是批處理逞力,包括Static Batching和Dynamic Batching。
Static Batching可以讓引擎降低任何尺寸網(wǎng)格的Draw Call糠爬,如下圖所示:
要讓場(chǎng)景中的物體使用Static Batching寇荧,需要將其標(biāo)記為Static,并在Mesh Renderer中共享相同的材質(zhì)执隧,因?yàn)镾tatic Batching不會(huì)在CPU上做頂點(diǎn)轉(zhuǎn)換揩抡,所以它通常比Dynamic Batching更有效户侥。不過它會(huì)使用更多的內(nèi)存,例如你的場(chǎng)景中有相同物體的多個(gè)副本峦嗤,Unity會(huì)將它們組合成一個(gè)大網(wǎng)格并可能會(huì)增加內(nèi)存使用蕊唐。Unity將盡可能多的網(wǎng)格結(jié)合到一個(gè)靜態(tài)網(wǎng)格中,并將其作為一個(gè)Draw Call提交烁设。這種方法的缺點(diǎn)是:標(biāo)記為Static的物體在其生命周期中不能移動(dòng)替梨。
Dynamic Batching啟用時(shí),Unity將嘗試自動(dòng)批量移動(dòng)物體到一個(gè)Draw Call中装黑。要使物體可以被動(dòng)態(tài)批處理副瀑,它們應(yīng)該共享相同的材質(zhì),但是還有一些其他限制:
頂點(diǎn)數(shù)量:Dynamic Batching場(chǎng)景中物體的每個(gè)頂點(diǎn)都有一定的開銷恋谭,因此批處理只適用于少于900個(gè)頂點(diǎn)屬性的網(wǎng)格物體糠睡。舉個(gè)例子,如果你的著色器使用頂點(diǎn)位置疚颊,法線和一個(gè)UV狈孔,那么你可以動(dòng)態(tài)批處理多達(dá)300個(gè)頂點(diǎn);而如果你的著色器使用頂點(diǎn)位置材义,法線均抽,UV0,UV1和切線其掂,那么只有180個(gè)頂點(diǎn)到忽。值得注意的是,屬性計(jì)數(shù)限制可能會(huì)在將來更改清寇。
鏡像信息:如果物體包含的Transform具備鏡像信息,例如A物體的大小是(1f, 1f, 1f)护蝶,而B物體的大小則是(-1f, -1f, -1f)华烟,則無法做批處理。
材質(zhì):如果物體使用不同的材質(zhì)實(shí)例持灰,即使它們本質(zhì)上相同盔夜,也不會(huì)被批量處理。而Shadow Caster Rendering是個(gè)例外堤魁。
渲染器:擁有光照貼圖的物體有其他渲染器參數(shù)喂链,例如光照貼圖索引或光照貼圖的偏移與縮放。一般來說妥泉,動(dòng)態(tài)光照貼圖的游戲?qū)ο髴?yīng)該指向要批量處理的完全相同光照貼圖的位置椭微。
不能使用Multi-pass著色器的情況:幾乎所有的Unity著色器都支持多個(gè)燈光的正向渲染模式(Forward Rendering),這要求額外的渲染次數(shù)盲链,所以繪制 “額外的每像素?zé)簟睍r(shí)不會(huì)被批處理蝇率;Legacy Deferred(Light Pre-Pass)渲染路徑不能被動(dòng)態(tài)批處理迟杂,因?yàn)樗仨毨L制物體兩次。
Dynamic Batching通過將所有物體的頂點(diǎn)轉(zhuǎn)換為CPU上的世界空間來工作本慕,所以它只能在渲染Draw Call的工作量小于CPU頂點(diǎn)轉(zhuǎn)換工作量的時(shí)候排拷,才會(huì)起到提高性能的作用。當(dāng)用游戲機(jī)或如Metal這樣的現(xiàn)代API锅尘,Draw Call的開銷通常低得多监氢,Dynamic Batching就無法提高性能了。了解到以上限制后藤违,如果明智地使用批處理浪腐,可以顯著提高您游戲的性能。
GPU Instancing
提高圖形性能的另一個(gè)好辦法是使用GPU Instancing纺弊。GPU Instancing的最大優(yōu)勢(shì)是可以減少內(nèi)存使用和CPU開銷牛欢。當(dāng)使用GPU Instancing時(shí),不需要打開批處理淆游,GPU Instancing的目的是一個(gè)網(wǎng)格可以與一系列附加參數(shù)一起被推送到GPU傍睹。要利用GPU Instancing,您必須使用相同的材質(zhì)犹菱,且可以傳遞額外的參數(shù)到著色器拾稳,如顏色,浮點(diǎn)數(shù)等腊脱。
Unity從5.4版本開始支持GPU Instancing访得。 唯一的限制是在游戲物體上要使用相同的材質(zhì)和網(wǎng)格。 目前支持以下平臺(tái):
Windows DX11/DX12 和 SM 4.0 或更高/OpenGL 4.1 或更高
OS X and Linux:OpenGL 4.1 and above
移動(dòng):OpenGL ES 3.0 或更高/Metal
PlayStation 4
Xbox One
如果您想要進(jìn)行進(jìn)一步的優(yōu)化陕凹,例如減少管理場(chǎng)景物體的開銷悍抑,您也可以使用Graphics.DrawMeshInstanced方法。 您只需要傳遞您的網(wǎng)格杜耙,材質(zhì)和附加屬性來繪制您的物體∷崖猓現(xiàn)在的限制是一次最多1023個(gè)實(shí)例。在Unity 5.6中佑女,我們添加了Graphics.DrawMeshInstancedIndirect的新方法记靡,可以用來指定需要渲染的實(shí)例數(shù)量。
GPU Instancing案例
要?jiǎng)?chuàng)建支持GPU Instancing的基本標(biāo)準(zhǔn)表面著色器团驱,可以在您的項(xiàng)目里面點(diǎn)擊:
Create->Shader->StandardSurfaceShader(Instanced)摸吠。
然后,在材質(zhì)屬性中選擇新創(chuàng)建的著色器嚎花。
雖然實(shí)例化的物體共享相同的網(wǎng)格和材質(zhì)寸痢,但您可以使用MaterialPropertyBlock API為每一個(gè)物體設(shè)置單獨(dú)的著色器屬性。
如果一個(gè)游戲?qū)ο蟊粯?biāo)記為“Static”并且打開了Static Batching贩幻,那么這個(gè)游戲?qū)ο缶筒荒苓M(jìn)行GPU Instancing轿腺,檢視器中會(huì)出現(xiàn)一個(gè)警告框两嘴,提示“靜態(tài)批處理”標(biāo)志可以在播放器設(shè)置(Player Settings)中取消。如果游戲?qū)ο笾С諨ynamic Batching族壳,但是它使用的某個(gè)材質(zhì)可以進(jìn)行實(shí)例化憔辫,那么這個(gè)游戲?qū)ο髮⒉粫?huì)被批處理,并且將被自動(dòng)實(shí)例化仿荆。
當(dāng)使用Forward Rendering渲染模式贰您,受多個(gè)燈光影響的物體無法有效地實(shí)例化。只有Base Pass可以有效地利用實(shí)例化拢操,而不是添加的Pass锦亦。此外,使用光照貼圖或受不同光或Reflection probe影響的物體無法實(shí)例化令境。如下圖所示杠园,您可以在Frame Debug中發(fā)現(xiàn)和GPU Instancing相關(guān)的Draw Call被標(biāo)記為“Draw Mesh(Instanced)”。
GPU Instancing是一個(gè)非常強(qiáng)大的功能舔庶。在Unity 5.6中抛蚁,您可以使用Graphics.DrawMeshInstancedIndirect繪制大量網(wǎng)格。在Mac Pro中惕橙,我們能夠畫出約68萬個(gè)具有不同顏色的移動(dòng)立方體并保持穩(wěn)定的60幀每秒的幀率瞧甩。
下圖是一個(gè)示例場(chǎng)景,超過6千個(gè)包子在天空中圍繞一個(gè)大碗飛翔弥鹦,它們都投射和接收陰影肚逸。由于使用了GPU Instancing,幾乎沒有性能開銷彬坏。這里的包子模型使用了StandardSurface Shader(Instanced)朦促。
總結(jié)
在本文中,我們描述了用于優(yōu)化渲染性能的兩種最流行的技術(shù):批處理和GPU Instancing栓始。我們向您展示了如何在實(shí)踐中使用它們并討論可能的應(yīng)用思灰。正因?yàn)橛兄T如批處理和GPU Instancing等優(yōu)化技術(shù)的存在,我們能夠繪制大量的對(duì)象并保持穩(wěn)定的性能混滔。