次世代手游美术资源优化干货分享
次世代,是日本流傳過(guò)來(lái)的叫法,意思是下一個(gè)時(shí)代,未來(lái)的時(shí)代,常說(shuō)的次世代科技,即指還未廣泛應(yīng)用的現(xiàn)金技術(shù)。后來(lái)這個(gè)名次變成了一個(gè)人們的習(xí)慣,將次世代變成一個(gè)名詞,用來(lái)代表某類(lèi)具備特定屬性的游戲類(lèi)型。
?
隨著科技的發(fā)展,手機(jī)硬件不斷升級(jí)優(yōu)化,使我們可以在移動(dòng)端上實(shí)現(xiàn)次世代游戲的畫(huà)面效果。雖然如此,我們還是受到一些硬件限制的瓶頸,我們不可能像之前制作主機(jī)游戲那樣“肆意浪費(fèi)、隨心所欲”,必須要優(yōu)化處理各種美術(shù)資源,以便在不同的平臺(tái),不同的硬件終端上有一個(gè)好的游戲體驗(yàn)。
性能瓶頸有哪些?
對(duì)于一個(gè)游戲來(lái)說(shuō),有兩種主要的計(jì)算資源:CPU和GPU。它們會(huì)互相合作,來(lái)讓我們的游戲可以在預(yù)期的幀率和分辨率下工作。CPU負(fù)責(zé)其中的幀率,GPU主要負(fù)責(zé)分辨率相關(guān)的一些東西。
總結(jié)起來(lái),主要的性能瓶頸在于:
CPU:
過(guò)多的Draw Calls
復(fù)雜的腳本或者物理模擬
GPU:
填充率:圖形處理單元美妙渲染的像素?cái)?shù)量
像素的復(fù)雜度:比如動(dòng)態(tài)陰影,光照,復(fù)雜的shader等等
幾何體的復(fù)雜度:頂點(diǎn)數(shù)量
GPU的顯存寬帶
涉及的優(yōu)化技術(shù)
對(duì)于CPU來(lái)說(shuō),限制它的主要是游戲中的Draw Calls,那么什么是Draw Calls呢?Draw Calls是CPU調(diào)用底層圖形接口,比如有上千個(gè)物體,每一個(gè)的渲染都需要去調(diào)用一次底層接口,而每一次的調(diào)用CPU都需要做很多工作,那么CPU必然不堪重負(fù)。但是對(duì)于GPU來(lái)說(shuō),圖形處理的工作量是一樣的,所以對(duì)Draw Calls的優(yōu)化,主要就是為了盡量解放CPU在調(diào)用圖形接口上的開(kāi)銷(xiāo)。
上面說(shuō)到過(guò),我們需要繪制圖像時(shí),就一定需要調(diào)用Draw Calls。例如,一個(gè)場(chǎng)景有水有樹(shù),我們渲染水的時(shí)候,使用的是一個(gè)matenall以及一個(gè)shader,但渲染樹(shù)的時(shí)候需要一個(gè)完全不同的matenall和shader,那么就需要CPU重新準(zhǔn)備頂點(diǎn)數(shù)據(jù)、重新設(shè)置shader,而這種工作實(shí)際上是非常耗時(shí)的。如果場(chǎng)景中,每一個(gè)物體都使用不同的matenall、不同的紋理。那么就會(huì)產(chǎn)生太多的Draw Call,影響幀率,游戲性能就會(huì)下降。其它COY的性能瓶頸還有物理、布料模擬、粒子模擬等,都是計(jì)算量很大的操作。
而對(duì)于GPU來(lái)說(shuō),它負(fù)責(zé)整個(gè)渲染流水線(xiàn),它會(huì)從處理CPU傳遞過(guò)來(lái)的模型數(shù)據(jù)開(kāi)始,進(jìn)行Vetex Shader、Fragment Shader等一系列工作,最后輸出屏幕上的每個(gè)像素。因此它的性能瓶頸可能和需要處理的頂點(diǎn)數(shù)目的、屏幕分辨率、顯存等了解了上面基本內(nèi)容后,下面涉及到的優(yōu)化技術(shù)有:
CPU優(yōu)化
減少Draw Call數(shù)量
GPU優(yōu)化
頂點(diǎn)數(shù)優(yōu)化
像素優(yōu)化
帶寬優(yōu)化
如何減少Draw Call數(shù)量?
1批處理(Batching)
最常見(jiàn)的就是通過(guò)批處理了。從名字上來(lái)解釋,就是一塊處理多個(gè)物體的意思,那么什么樣的物體可以一起處理呢?答案是使用同一個(gè)材質(zhì)的物體。因此,對(duì)于同一材質(zhì)的物體,它們之間的不同僅僅在于頂點(diǎn)數(shù)據(jù)的差別,即使用的網(wǎng)絡(luò)不同而已。我們可以把這些頂點(diǎn)數(shù)據(jù)合并在一起,再一起發(fā)送給GPU,就可以完成一次批處理。
?
Unity中含有兩種批處理方式:一種是動(dòng)態(tài)批處理,一種是靜態(tài)批處理。
對(duì)于動(dòng)態(tài)批處理來(lái)說(shuō),好消息是一切處理都是自動(dòng)的,不需要我們自己做任何操作,而且物體是可以移動(dòng)的。但壞消息是,限制很多,可能一不小心我們就會(huì)破壞這種機(jī)制,導(dǎo)致unity無(wú)法批處理一些使用了相同材質(zhì)的物體。對(duì)于靜態(tài)批處理來(lái)說(shuō),好消息是自由度很高,限制很少,壞消息是可能會(huì)占用更多的內(nèi)存,而且經(jīng)過(guò)靜態(tài)批處理后的所有物體都不可以再移動(dòng)了。
首先來(lái)說(shuō)動(dòng)態(tài)批處理。
Unity進(jìn)行動(dòng)態(tài)批處理的條件是,物體使用同一材質(zhì)并且滿(mǎn)足一些特定條件。Unity總是在不知不覺(jué)中就為我們做了動(dòng)態(tài)批處理。動(dòng)態(tài)批處理雖然自動(dòng)的令人感動(dòng),但是它對(duì)模型的要求很多。
1、頂點(diǎn)熟悉的最大限制為900。
2、物體都必須需要使用同一個(gè)縮放尺度(可以是(1,1,1)、(1,2,3)、(1.5、1.4、1.3)等等,但必須都一樣)。但如果是非統(tǒng)一縮放(即每個(gè)維度的縮放尺度不一樣)。例如(1,2,1)),那么如果所有的物體都是使用不同的非統(tǒng)一縮放也是可以批處理的。
3、使用lightmap的物體不會(huì)動(dòng)態(tài)批處理,多passes的shader會(huì)中斷批處理,接受實(shí)時(shí)陰影的物體也不會(huì)批處理。
動(dòng)態(tài)批處理的條件這么多,因此unity提供了另一個(gè)方法,靜態(tài)批處理。方法很堅(jiān)定,只需要把物體的“Static Flag”勾選上。
有一些小提示可以使用:
1、盡可能選擇靜態(tài)批處理,但得時(shí)刻小心對(duì)內(nèi)存的消耗
2、如果無(wú)法進(jìn)行靜態(tài)批處理,而要使用動(dòng)態(tài)批處理的話(huà),那么小心上面提到的各種注意事項(xiàng)。例如:
盡可能讓這樣的物體少并且盡可能讓這些物體包涵少量的頂點(diǎn)屬性。
不要使用統(tǒng)一縮放,或者都使用不同的非統(tǒng)一縮放。
3、對(duì)于游戲中的小道具,可以使用動(dòng)態(tài)批處理。
4、對(duì)于包含動(dòng)畫(huà)的這類(lèi)物體,我們無(wú)法全部使用靜態(tài)批處理,但其中如果有不動(dòng)的部分,可以把這部分標(biāo)識(shí)成“Static”。
雖然批處理是個(gè)很好的方式,但很容易就打破它的規(guī)定。例如,買(mǎi)域名場(chǎng)景中的物體都使用Diffuse材質(zhì),但它們可能會(huì)使用不同的紋理。因此,盡可能把多張小紋理合并到一張大紋理中是一個(gè)好主意。
GPU的優(yōu)化
1頂點(diǎn)優(yōu)化
(1)優(yōu)化Mesh,減少頂點(diǎn)數(shù)量。
3D游戲制作都是由模型制作開(kāi)始,而在建模的時(shí)候,有一條我們需要記住,盡可能減少模型中三角形的數(shù)目,一些對(duì)于模型沒(méi)有影響,或是肉眼非常難察覺(jué)到區(qū)別的頂點(diǎn)都要盡可能去掉。
(2)LOD技術(shù)
LOD技術(shù)有點(diǎn)類(lèi)似于Mipmap技術(shù),不同的是,LOD是對(duì)模型建立了一個(gè)模型金字塔。根據(jù)攝像機(jī)距離對(duì)象的遠(yuǎn)近,選擇使用不同精度的模型,它的好處是可以在適當(dāng)?shù)臅r(shí)候大量減少需要繪制的頂點(diǎn)數(shù)目。它的缺點(diǎn)同樣是需要占用更多的內(nèi)存,而且如果沒(méi)有調(diào)整后距離的話(huà),可能會(huì)造成模擬的突變。
在unity中,可以通過(guò)LOD Group來(lái)實(shí)現(xiàn)LOD技術(shù)。
(3)遮擋剔除(Occlusion culling)技術(shù)
遮擋剔除是用來(lái)清除躲在其他物件后面看不到的物件,這代表資源不會(huì)浪費(fèi)在計(jì)算那么像看不到的頂點(diǎn)上,進(jìn)而提升性能。
2像素優(yōu)化
(1)控制繪制順序
像素優(yōu)化的重點(diǎn)在于減少overdraw。之前提過(guò),overdraw指的就是一個(gè)像素被繪制了多次,關(guān)鍵在于控制繪制的順序。
Unity還提供了查看overdraw的視圖,當(dāng)然這里的視圖只是提供了查看物體遮擋的層數(shù)關(guān)系,并不是真正的最終屏幕繪制的overdraw。也就是說(shuō),可以理解為它顯示的是如果沒(méi)有使用任何深度檢驗(yàn)時(shí)的overdraw,這種視圖是通過(guò)把所有對(duì)象都渲染成一個(gè)透明的輪廓,通過(guò)查看透明顏色的累計(jì)程度,來(lái)判斷物體的遮擋。
需要控制繪制順序,主要原因是為了最大限度的避免overdraws,也就是同一個(gè)位置的像素可以需要被繪制多變。在PC上,資源無(wú)限,為了得到最準(zhǔn)確的渲染結(jié)果,繪制順序可能是從后往前繪制不透明物體,然后再繪制透明物體進(jìn)行混合。但在移動(dòng)平臺(tái)上,這種會(huì)造成大量overdraw的方式顯然是不合適的,我們應(yīng)該盡量從前往后繪制。從前往后繪制之所以可以減少overdraw,都是因?yàn)樯疃葯z驗(yàn)的功勞。
在unity中,哪些shader中被設(shè)置為“Geometry”隊(duì)列的對(duì)象總是從前往后繪制的,而其它固定隊(duì)列的物體,則都是從后往前繪制的。這意味著,我們可以盡量把物體的隊(duì)列設(shè)置為“Geometry”。而且,我們還可以充分利用unity的隊(duì)列來(lái)控制繪制順序。
(2)警惕透明物體的使用
對(duì)于透明對(duì)象,由于它本身的特性決定如果要得到正確的渲染效果,就必須從后往前渲染,而且拋棄了深度檢驗(yàn)。這意味著,透明物體幾乎一定會(huì)造成overdraws。如果我們不注意這一點(diǎn),在一些機(jī)器上可能會(huì)造成嚴(yán)重的性能損失。例如,對(duì)于GUI對(duì)象來(lái)說(shuō),它們大多被設(shè)置成了半透明,如果屏幕中GUI占據(jù)的比例太多,而主攝像機(jī)又沒(méi)有進(jìn)行調(diào)整而是投影整個(gè)屏幕,那么GUI就會(huì)造成屏幕大量的overdraws。
因此,如果場(chǎng)景中有大量的透明對(duì)象,或者有很多層覆蓋的多層透明對(duì)象(即使它們每個(gè)的面積都不大)。或者是透明的粒子效果,在移動(dòng)設(shè)備上也會(huì)造成大量的overdraws,這是應(yīng)該盡量避免的。
對(duì)于上述的GUI這種情況,我們可以盡量減少窗口中的GUI所占的面積,如果實(shí)在無(wú)能為力,我們可以把GUI繪制和三位場(chǎng)景的繪制交給不同的攝像機(jī)。而其中負(fù)責(zé)三位場(chǎng)景的攝像機(jī)的視角范圍盡量不要和GUI重疊。對(duì)于其他情況,只能說(shuō),盡可能少用。當(dāng)然這樣會(huì)對(duì)游戲的美觀(guān)度產(chǎn)生一定影響,因此我們可以在代碼中對(duì)激起的性能進(jìn)行判斷,例如首先關(guān)閉所有的耗費(fèi)性能的功能,如果發(fā)現(xiàn)這個(gè)激起表現(xiàn)非常良好,再?lài)L試開(kāi)啟一些特效功能。
(3)盡量避免實(shí)時(shí)光照
實(shí)時(shí)光照對(duì)于移動(dòng)平臺(tái)是個(gè)非常昂貴的操作。如果只有一個(gè)平行光還好,但如果場(chǎng)景中包含了太多光源并且使用了很多Passes的shader,那么很有可能會(huì)造成性能下降。而且在有些機(jī)器上,還要面臨shader失效的風(fēng)險(xiǎn)。例如,一個(gè)場(chǎng)景里如果包含了三個(gè)逐像素的點(diǎn)光源,而且使用了逐像素的shader,那么很可能將Draw Calls提高了三倍,同時(shí)也會(huì)增加overdraws,這是因?yàn)?#xff0c;對(duì)于逐像素的光源來(lái)說(shuō),被這些光源照亮的物體要被再渲染一次。更糟糕的是,無(wú)論是動(dòng)態(tài)批處理還是靜態(tài)批處理,對(duì)于這種逐像素的pass都無(wú)法進(jìn)行批處理,也就是說(shuō),它們會(huì)中斷批處理。
3帶寬優(yōu)化
(1)使用Texture Atlas
使用Texture Atlas可以幫助減少Draw Calls,而這些紋理的大小同樣是一個(gè)需要考慮的問(wèn)題。在這之前要提到一個(gè)問(wèn)題就是,所有紋理的長(zhǎng)寬比最好是正方形,而且長(zhǎng)度值最好是2的整數(shù)冪,這是因?yàn)楹芏鄡?yōu)化策略只有在這種時(shí)候才可以發(fā)揮最大的效用。
(2)關(guān)于Generate Mip Maps
Generate Mip Maps會(huì)為同一張紋理創(chuàng)建出很多不同大小的小紋理,構(gòu)成一個(gè)紋理金字塔,而在游戲中,可以根據(jù)距離物體的遠(yuǎn)近,來(lái)動(dòng)態(tài)選擇使用哪一個(gè)紋理。
這是因?yàn)?#xff0c;在距離物體很遠(yuǎn)的時(shí)候,就算我們使用了非常精細(xì)的紋理,但肉眼也是分辨不出來(lái)的,這種時(shí)候完全可以使用更小、更模糊的紋理來(lái)代替,而這可以節(jié)省大量訪(fǎng)問(wèn)的像素的數(shù)目。但它的缺點(diǎn)是,由于需要為每個(gè)紋理簡(jiǎn)歷一個(gè)圖像金字塔,因此它會(huì)需要占用更多的內(nèi)存。
(3)優(yōu)化紋理尺寸大小、壓縮格式
紋理尺寸大小:
紋理尺寸大小通過(guò)MaxSize設(shè)置,它決定了紋理的長(zhǎng)寬值,如果我們使用的紋理本身超過(guò)了這個(gè)最大值,unity會(huì)對(duì)其進(jìn)行縮小來(lái)滿(mǎn)足這個(gè)條件。
這里特別說(shuō)明一點(diǎn),所有紋理的長(zhǎng)寬比最好是正方形,而且長(zhǎng)度值最好是2的整數(shù)冪,例如64、128等。這是因?yàn)橛泻芏鄡?yōu)化策略只有在這種時(shí)候才可以發(fā)揮最大的效用。
壓縮格式:
壓縮格式通過(guò)Format設(shè)置,Format負(fù)責(zé)紋理使用的壓縮格式。通常選擇這種自動(dòng)模式就可以了。Unity會(huì)負(fù)責(zé)根據(jù)不同的平臺(tái)來(lái)選擇合適的壓縮模式。對(duì)于GUI類(lèi)型的紋理,我們可以根據(jù)對(duì)畫(huà)質(zhì)的要求來(lái)選擇是否進(jìn)行壓縮。我們還可以根據(jù)不同的激起來(lái)選擇使用不同的分辨率的紋理,以便讓游戲在某些老機(jī)器上也可以運(yùn)行。例如在安卓平臺(tái)上,我們的壓縮模式會(huì)采用RGB Compresses ETC 4 Bits。在ios平臺(tái)上,我們采用的壓縮模式是RGB Compresses PVRTC4 Bits。
注:手游圈內(nèi)人整理自創(chuàng)夢(mèng)天地開(kāi)發(fā)者邵雷的“關(guān)于次世代手游美術(shù)資源的優(yōu)化”的主題演講。
總結(jié)
以上是生活随笔為你收集整理的次世代手游美术资源优化干货分享的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 加速 VR 渲染地狱难度进阶篇:降低图形
- 下一篇: 杨清彦:《像三国》游戏3D动效制作经验分