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