在Unity3D中的渲染優(yōu)化-批處理技術

在Unity3D中瑞眼,常用的減少Draw call的優(yōu)化技術就是批處理技術吗铐。批處理的原理是減少每一幀需要的Draw call數目息楔。為了把一個對象渲染到屏幕上妒峦,CPU需要檢查哪些光源影響了該物體重斑,綁定shader并設置它的參數,再把渲染命令發(fā)送給GPU肯骇。當場景中包含了大量的對象時窥浪,這些操作就會非常耗時。例如笛丙,如果我們需要渲染一千個三角形漾脂,把它們按一千個單獨的網格進行渲染所花費的時間要遠遠大于渲染一個包含一千個三角形的網格。在這兩種情況下胚鸯,GPU的性能消耗其實并沒有多大的區(qū)別符相,但CPU的draw call數目就會成為性能瓶頸。因此蠢琳,批處理的思想很簡單啊终,就是在每次調用draw call時盡可能多地處理多個物體。

使用同一材質的物體可以進行批處理傲须,因為對于使用同一材質的物體蓝牲,它們之間的不同僅僅在于頂點數據的差別。我們可以把這些頂點數據合并在一起泰讽,再一起發(fā)送給GPU例衍,這樣就可以完成一次批處理。

在Unity中支持兩種類型的批處理已卸,一種是動態(tài)批處理佛玄,另一種是靜態(tài)批處理。對于動態(tài)批處理來說累澡,優(yōu)點是一切處理Unity自動完成的梦抢,不需要我們做任何操作,而且物體可以是移動的愧哟,缺點是限制有很多奥吩,可能一不小心就會破壞了這種機制哼蛆,導致Unity無法動態(tài)批處理一些使用了相同材質的物體。而對于靜態(tài)批處理來說霞赫,它的優(yōu)點是自由度很高腮介,限制很少;但缺點是可能會占用更多的內存端衰,而經過靜態(tài)批處理后的所有物體都不可以再移動了(即便在腳本中嘗試改變物體的位置也是無效的)叠洗。

Unity3D中的動態(tài)批處理技術

動態(tài)批處理的原理是,每一幀把可以進行批處理的模型網格進行合并旅东,再把合并后的模型數據傳遞給GPU灭抑,然后使用同一個材質對其渲染。除了實現方便玉锌,動態(tài)批處理的另一個好處就是名挥,經過批處理的物體仍然可以移動疟羹,這是由于在處理每幀時Unity都會重新合并一次網格主守。

雖然Unity的動態(tài)批處理不需要我們進行任何額外工作,但只有滿足條件的模型和材質才可以被動態(tài)批處理榄融。(需要注意的是参淫,隨著Unity版本的變化,這些條件也有一些改變)這些條件限制是:

1.能夠進行動態(tài)批處理的網格的頂點屬性規(guī)模要小于900.例如愧杯,如果shader中需要使用頂點位置涎才,法線和紋理坐標這三個頂點屬性,那么要想讓模型能夠被動態(tài)批處理力九,它的頂點數目不能超過300.需要注意的是耍铜,這個數字在未來有可能會發(fā)生變化,因此不要依賴這個數據跌前。

2.一般來說棕兼,所有對象都需要使用同一縮放尺度(可以是(1,1抵乓,1)伴挚,(1,2灾炭,3)茎芋,(1.5,1.4蜈出,1.3)等田弥,但必須都一樣)。一個例外情況是铡原,如果所有的物體都是用了不同的非統(tǒng)一縮放皱蹦,那么他們也是可以被動態(tài)批處理的煤杀。但在Unity5中,這種對模型縮放的限制已經不存在了沪哺。

3.對于使用光照貼圖紋理的物體需要小心處理沈自。這些物體需要額外的渲染參數,例如辜妓,在光照貼圖紋理上的索引和偏移量以及縮放信息等因此枯途,為了讓這些物體可以被動態(tài)批處理,我們需要保證它們指向光照貼圖紋理中的同一個位置籍滴。

4.有多個Pass通道的shader會中斷批處理酪夷。在前向渲染中,我們有時需要使用額外的Pass來為模型添加更多的光照效果孽惰,但這樣一來模型就不會被動態(tài)批處理了晚岭。

Unity3D中的靜態(tài)批處理技術

靜態(tài)批處理的實現原理是,只在運行的開始階段勋功,把需要進行靜態(tài)批處理的模型合并到一個新的網格結構中坦报,這意味著這些模型不可以在運行時刻被移動。但由于它只需要進行一次合并操作狂鞋,因此比動態(tài)批處理更加高效片择。但靜態(tài)批處理的缺點是需要占用更多的內存來存儲合并后的幾何結構。這時因為骚揍,如果在靜態(tài)批處理前一些物體共享了相同的網格字管,那么在內存中每一個物體都會對應一個該網格的復制品,即一個網格會變成多個網格再發(fā)送給GPU信不。如果這類使用相同網格的對象很多嘲叔,那么這就會成為一種性能瓶頸了。例如抽活,如果在一個使用了1000個相同樹模型的森林中使用靜態(tài)批處理硫戈,那么就會多使用1000倍的內存,這會造成嚴重的內存影響酌壕。這時的解決方法就是要么忍受這種犧牲內存換取性能的方法掏愁,要么不要使用靜態(tài)批處理,而使用動態(tài)批處理技術(但要小心控制模型的頂點屬性數目)卵牍,或者自己編寫批處理方法果港。

在Unity中使用靜態(tài)批處理的方法是,在場景中選中需要靜態(tài)批處理的物體糊昙,在其Inspector面板的右上角勾選上Batching static靜態(tài)屬性辛掠。在內部實現上,Unity首先把這些靜態(tài)物體變換到世界空間下,然后為它們構建一個更大的頂點和索引緩存萝衩,對于使用同一材質的物體回挽。Unity只需要調用一個drawcall就可以繪制全部物體。而對于使用不同材質的物體猩谊,靜態(tài)批處理同樣可以提升渲染性能千劈。盡管這些物體仍然需要調用多個draw call,但靜態(tài)批處理可以減少這些draw call之間的狀態(tài)切換牌捷,而這些切換往往是費時的操作墙牌。

我們可以在Unity的分析器中觀察到應用靜態(tài)批處理前后VBO total(Vertex Buffer Object,頂點緩存對象)的變化暗甥。在一些物體共享了相同的網格的情況下喜滨,我們可以看到這些物體在使用了靜態(tài)批處理技術后,VBO total的數目變大了撤防,這正是因為靜態(tài)批處理會占用更多內存的緣故虽风。正如上面所講,靜態(tài)批處理需要占用更多的內存來存儲合并后的幾何結構寄月,如果一些物體共享了相同的網格辜膝,那么在內存中每個物體都會對應一個該網格的復制品。

如果場景中包含了除了平行光以外的其他光源剥懒,并且在Shader中定義了額外的Pass來處理它們内舟,這些額外的Pass部分是不會被批處理的合敦,但是處理平行光的Base Pass部分仍然會被靜態(tài)批處理初橘。

Unity3D中使用共享材質

無論是動態(tài)批處理還是靜態(tài)批處理,都要求模型之間需要共享同一個材質充岛。但不同的模型之間總會需要有不同的渲染屬性保檐,例如,使用不同的紋理崔梗,顏色等夜只。這時我們需要一些策略來盡可能的合并材質。

如果兩個材質之間只有使用的紋理不同蒜魄,我們可以把這些紋理合并到一張更大的紋理中扔亥,這張更大紋理被稱為是一張圖集(atlas)。一旦使用了同一紋理谈为,我們就可以使用同一材質旅挤,再使用不同的采樣坐標對紋理采樣即可。

但有時除了紋理不同外伞鲫,不同的物體在材質上還有一些微小的參數變化粘茄,例如,顏色不同,某些浮點屬性不同柒瓣。但是儒搭,不管是動態(tài)批處理還是靜態(tài)批處理,它們的前提都是使用同一個材質芙贫。是同一個搂鲫,而不是使用了同一shader的材質,也就是說它們指向的材質必須是同一個實體磺平。這意味著默穴,只要我們調整了參數,就會影響到所欲使用這個材質的對象褪秀。那么想要微小的調整怎么辦呢蓄诽?一種常用的方法就是使用網格的頂點數據來存儲這些參數(最常見的就是頂點顏色數據)。

經過批處理后的物體會被處理成更大的VBO發(fā)送給GPU媒吗,VBO中的數據可以作為輸入傳遞給頂點著色器仑氛,因此,我們可以巧妙地對VBO中的數據進行控制闸英,從而達到不同效果的目的锯岖。一個例子就是,森林場景中的所有樹使用了同一材質甫何,我們希望它們可以通過批處理來減少draw call出吹,但不同樹的顏色可能不同。這時辙喂,我們可以利用網格頂點的顏色數據來調整捶牢。

需要注意的是,如果我們需要在腳本中訪問共享材質巍耗,應該使用Renderer.sharedMaterial來保證修改的是和其他物體共享的材質秋麸,但這意味著修改會應用到所有使用該材質的物體上。另一個類似的API是Renderer.material炬太,如果使用Renderer.material來修改材質灸蟆,Unity會創(chuàng)建一個該材質的復制品,從而破壞批處理在該物體上的應用亲族。

關于在Unity3D中使用批處理的注意事項:

1.盡可能的使用靜態(tài)批處理炒考,但要時刻小心對內存的消耗,并且記住經過靜態(tài)批處理的物體不可以再被移動霎迫。

2.如果無法進行靜態(tài)批處理斋枢,而要使用動態(tài)批處理的話,那么盡可能減少物體的數目并且讓這些物體包含少量的頂點屬性和頂點數目女气。

3.對于游戲中的小道具杏慰,例如可以撿拾的金幣等,可以使用動態(tài)批處理。

4.對于動畫的這類物體缘滥,我們無法全部使用靜態(tài)批處理轰胁,但其中如果有不動的部分,可以把這部分標識成“Static”朝扼。

5.由于批處理需要把模型變換到世界空間下再合并它們赃阀,因此,如果shader中存在一些基于模型空間下坐標的運算擎颖,那么往往會得到錯誤的結果榛斯。一個解決方法是,在shader中使用DisableBatching標簽強制使該shader的材質不會被批處理搂捧。

6.使用半透明材質的物體通常需要使用嚴格的從后往前的繪制順序來保證透明混合的正確性驮俗。這意味著,當繪制順序無法滿足時允跑,批處理無法在這些物體上被成功地應用王凑。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市聋丝,隨后出現的幾起案子索烹,更是在濱河造成了極大的恐慌,老刑警劉巖弱睦,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件百姓,死亡現場離奇詭異,居然都是意外死亡况木,警方通過查閱死者的電腦和手機垒拢,發(fā)現死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來焦读,“玉大人子库,你說我怎么就攤上這事舱权〈;危” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵宴倍,是天一觀的道長张症。 經常有香客問我,道長鸵贬,這世上最難降的妖魔是什么俗他? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮阔逼,結果婚禮上兆衅,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好羡亩,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布摩疑。 她就那樣靜靜地躺著,像睡著了一般畏铆。 火紅的嫁衣襯著肌膚如雪雷袋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天辞居,我揣著相機與錄音楷怒,去河邊找鬼。 笑死瓦灶,一個胖子當著我的面吹牛鸠删,可吹牛的內容都是我干的。 我是一名探鬼主播贼陶,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼冶共,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了每界?” 一聲冷哼從身側響起捅僵,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎眨层,沒想到半個月后庙楚,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡趴樱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年馒闷,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叁征。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡纳账,死狀恐怖,靈堂內的尸體忽然破棺而出捺疼,到底是詐尸還是另有隱情疏虫,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布啤呼,位于F島的核電站卧秘,受9級特大地震影響,放射性物質發(fā)生泄漏官扣。R本人自食惡果不足惜翅敌,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望惕蹄。 院中可真熱鬧蚯涮,春花似錦治专、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至液肌,卻和暖如春挟炬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嗦哆。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工谤祖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人老速。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓粥喜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親橘券。 傳聞我的和親對象是個殘疾皇子额湘,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內容