本文的主要目的是學(xué)習(xí)減少Draw Call來(lái)使你的游戲幀率更高
盡管圖形是如此簡(jiǎn)單,為什么我的游戲延遲這么多? 為什么我的游戲加載時(shí)間如此之高? 為什么屏幕之間的切換如此之慢? 為什么我游戲的FPS一直很低? 我已經(jīng)壓縮過(guò)紋理貼圖和精靈了,怎么還那么大? 為什么我的游戲總會(huì)崩潰? 為什么我的游戲那么費(fèi)電? 為什么在手機(jī)上運(yùn)行我的游戲時(shí),手機(jī)發(fā)熱怎么會(huì)那么嚴(yán)重?
在游戲開(kāi)發(fā)的某個(gè)階段,我們都會(huì)遇到這些問(wèn)題。我們會(huì)試著分析新的圖形技術(shù)、新的圖像壓縮技術(shù)、新的代碼以及一些其他技術(shù)。因此,這讓我們犧牲了很多寶貴時(shí)間,而在最后的最后,或許我們解決了一些棘手的問(wèn)題亦或是放棄了這些新技術(shù)。 在這里,我們會(huì)盡量減少這樣的常見(jiàn)錯(cuò)誤以及縮短困難期。其實(shí)我更愿意說(shuō)忽視Draw Call是粗心大意而不是一個(gè)錯(cuò)誤。
Draw Call僅僅是一條指令!Draw Call指令從CPU傳到GPU,渲染一個(gè)網(wǎng)格。指令只指向一個(gè)被渲染的網(wǎng)格并且不包含任何材質(zhì)信息。(請(qǐng)容忍我一段時(shí)間,我保證后面的會(huì)更容易理解一些:D)
在發(fā)出指令后,GPU的渲染狀態(tài)值(材質(zhì)、紋理、shader等)和所有的頂點(diǎn)數(shù)據(jù)通過(guò)神奇的代碼轉(zhuǎn)化為以一個(gè)信息,然后再在你的屏幕上呈現(xiàn)出美麗的畫(huà)面。 渲染就是在做一個(gè)巨大數(shù)量的小任務(wù),比如計(jì)算成千上萬(wàn)的頂點(diǎn)和在屏幕上繪制以百萬(wàn)計(jì)的像素。
每個(gè)用不同的材料的網(wǎng)格都需要一個(gè)單獨(dú)的Draw call。
讓我來(lái)舉個(gè)容易理解的例子。下面,我們用一個(gè)簡(jiǎn)單的UI面板來(lái)幫助你理解這個(gè)概念。
步驟1)按你的喜好創(chuàng)建UI 我已經(jīng)創(chuàng)建好了,如下圖所示:
就像你看到的那樣,這是個(gè)有少量圓形和矩形的基本界面。
我使用了如下精靈
步驟2)檢查Draw Calls
運(yùn)行游戲,并點(diǎn)擊Game視圖中的stats按鈕
如下圖所示,你會(huì)看到游戲在運(yùn)行時(shí)的一些渲染數(shù)據(jù)。
這里,Batches是個(gè)重要的指標(biāo)。需要注意的是,Batches值越低,Draw Calls就越低。
步驟3)打開(kāi)幀調(diào)試窗口
注意這個(gè)功能只有在Unity5.0以上版本才有。
下面是Unity官方文檔的介紹 “幀調(diào)試器可以讓你凍結(jié)回放運(yùn)行中游戲的某一幀,然后看那一幀渲染的draw calls。和列出draw calls一樣,幀調(diào)試器也允許你逐幀調(diào)試,所以你可以看到場(chǎng)景如何從它的圖形元素構(gòu)建的大量細(xì)節(jié)”
那么讓我們通過(guò)點(diǎn)擊幀框架上的“Enable”按鈕來(lái)分析一下draw calls吧。
點(diǎn)擊激活frame就會(huì)被暫停并顯示要求我們畫(huà)一塊屏幕。 在我的例子中,它是十個(gè)batches,并且根據(jù)你屏幕會(huì)看到不同數(shù)量的Batches
你可以滾動(dòng)瀏覽每個(gè)Draw Call去查看每個(gè)生成的屏幕結(jié)果。
OK!我能看到一些Draw Call,那么我為什么要關(guān)心這個(gè)呢?
正如我之前所說(shuō)的,這取決于你的硬件水平,即使它是一個(gè)簡(jiǎn)單的UI,也可能用了10個(gè)Draw Call去畫(huà)滿整個(gè)屏幕。
現(xiàn)在想象一下一個(gè)完整的游戲需要多少Draw Call?
大量的Draw Call會(huì)在每一幀生成成千上萬(wàn)的網(wǎng)格。很明顯減少它們將減少GPU開(kāi)銷(xiāo)。
“現(xiàn)代桌面級(jí)游戲可以每幀處理500-5000 draw call。而移動(dòng)端大約只能處理40到60個(gè),最新的移動(dòng)設(shè)備則可以處理120到160個(gè)draw call”
所以draw call會(huì)成為一個(gè)很大的瓶頸!記住幀率既是王道!!
如果你的幀率很好,不需要擔(dān)心craw call。
大量的Draw Call會(huì)嚴(yán)重影響硬件的表現(xiàn),并且每一幀都需要完成Draw Call
噢...我現(xiàn)在知道了,Draw Call是罪魁禍?zhǔn)?,但怎么解決呢?
幸運(yùn)的是,在unity中有一個(gè)叫Sprite Packer的工具救了我們!
Unity官網(wǎng)原話:“為了獲得最佳性能,最好將幾個(gè)精靈紋理打包在一起成為一個(gè)圖集。Unity提供一個(gè)雪碧包實(shí)用工具,它可以將單獨(dú)的精靈紋理自動(dòng)打包成一個(gè)圖集”
現(xiàn)在我們將演示一個(gè)將多個(gè)精靈打包成圖集的Demo。
步驟1)選擇你想要的打包的精靈
理想的UI,應(yīng)該將屏幕上的所有UI元素打包到一個(gè)單獨(dú)的表中。
步驟2)給這個(gè)包一個(gè)標(biāo)簽,如下圖所示:
這里,我命名為MainScreen,你可以命名你喜歡的名字。
步驟3)打開(kāi)Sprite Packer窗口并整理
下圖就是Sprite Packer窗口
點(diǎn)擊Pack按鈕
根據(jù)包名標(biāo)簽會(huì)將大量紋理打包到此一個(gè)圖集中。
你可以通過(guò)下拉菜單查看圖集上的圖片。
如果紋理貼圖沒(méi)有打包到一個(gè)圖集,他們會(huì)被分到一個(gè)子頁(yè)。
你可以選擇打包的算法。
步驟4)運(yùn)行游戲!
你看到改變了嗎?
查看stats選項(xiàng)卡的Batches值。
我的batches從一開(kāi)始的10降到了3!這減少了7個(gè)Draw Call!這意味著渲染能力提高了兩倍!同時(shí)也降低了GPU負(fù)擔(dān)!
想象一下實(shí)際情況,從500降低到200是一個(gè)巨大的提升!特別是對(duì)移動(dòng)端來(lái)說(shuō)!減少CPU的負(fù)擔(dān)的同時(shí)讓其他程序正常運(yùn)行。
這對(duì)渲染是個(gè)巨大的提升!(譯者注:感覺(jué)這個(gè)Demo的鋪墊好長(zhǎng)啊QAQ)
這對(duì)渲染是個(gè)巨大的提升?。ㄗg者注:感覺(jué)這個(gè)Demo的鋪墊好長(zhǎng)啊QAQ)
原文作者:Rudra Gesota 原文鏈接:http://www./blog/learn-draw-call-reduction-and-make-your-games-run-superfast
|