unity 靜態批處理原理理解
目錄
- 一、靜態批處理的時間點
- 二、靜態批處理的基本原理
- 三、為什么要用靜態批處理?
- 四、對于靜態批處理后的物體,如何決定其可視?
一、靜態批處理的時間點
在游戲匯出的時候,在player setting中勾選static batching,這樣在匯出包的時候就進行批處理,匯出來的包就會比較大,
在游戲場景中勾選場景物體的static選項,在加載該場景的時候,會進行一次靜態批處理的合并,這樣匯出來的包不大,但是在加載的時候會使得記憶體變大,
二、靜態批處理的基本原理
場景中有4個物體,ABCD,如果都勾選靜態選項,在進行靜態批處理的時候,引擎會判斷這四個物體是否共用同一渲染材質,
如果共用同一渲染材質,則會將這四個物體視為可以批處理的物件,引擎會基于單個渲染物件的大小拷貝出3個,總共變為4個mesh,此時這4個mesh會存在一個index buffer中,此時會讓資源占用的記憶體變大4倍,這樣在渲染的時候,是將這個更大的mesh傳遞給GPU進行渲染操作的,
三、為什么要用靜態批處理?
在游戲的運行中,有時候CPU的瓶頸也會至關重要,如果CPU的運行速度較慢,則GPU會出現等待CPU的情況,此時游戲主要受到CPU的限制,
CPU在游戲中的主要分工,主要分為兩個部分:設定渲染狀態和呼叫DC, 其中設定渲染狀態屬于比較重要的分工,對于加載到游戲中的資源和物件等,CPU需要計算其頂點相關的矩陣,渲染所用的貼圖,渲染所用到的材質和shader,渲染所用到的燈光等,
如果每個物體的材質和貼圖等都不一樣,此時CPU的主要作業就是設定這些物體的渲染狀態(當然呼叫DC也會更多,但此時渲染狀態的改變更消耗性能,也就是setPass),游戲的運行會比較緩慢,所以在常見的游戲中,對于大量的不需要改變位置的物體,都會采用靜態批處理的方式來解決渲染狀態的瓶頸,
采用批處理的方式,對于相同渲染材質的物體,會合并成一個更大的渲染物件mesh來進行渲染,這時候設定合并后的渲染物件的渲染狀態,與設定合并前的多個渲染物件的渲染狀態相比會大大減小次數,
此外對于大部分的渲染物件,主要的判斷依據就是渲染狀態和位置矩陣相關的引數,如果渲染狀態一致,則基本可以視為同一個批處理的物件,然后對于位置矩陣進行單獨的設定即可,其實在引擎的內部,對于需要渲染的物件也會進行一個渲染排序,會優先將渲染狀態相同的排在一起進行設定,這樣渲染狀態的切換就不會過于頻繁,
通過批處理的方式來降低渲染狀態的切換次數,可以極大的優化CPU的渲染瓶頸,所以在很多時候會采用靜態批處理的方式來優化CPU的瓶頸,
四、對于靜態批處理后的物體,如何決定其可視?
對于靜態批處理后的物體,比如ABCD,那么如何在實際的游戲中去具體的渲染ABCD中的那幾個可見(位于相機的視錐體內)? 這需要解釋一下批處理的合并方式:在unity5中,會構建一個更大的記憶體buffer空間,依次存放ABCD的資料,
在渲染A的時候,會呼叫DX的介面來取這份buffer中的指定起始點和長度的資料出來,傳遞到GPU中進行渲染,如果需要渲染AD兩個物件,則會在前面的基礎上,再將整體取出來(因為D存在末尾),然后傳遞到GPU中進行渲染,注意此時是整體傳遞A或者ABCD的資料,不會在CPU進行裁剪的作業,具體的A的哪部分可見,是在GPU的頂點裁剪程序中進行的,
此時相當于要進行兩次渲染,渲染的次數增大了,這樣當然會帶來一定的性能損耗,但是相對于渲染狀態的設定改變帶來的性能損耗,是可以接受的,游戲中如果大量的物體都采用靜態批處理,此時會出現很大的記憶體buffer,如果渲染頭和尾部的物體,則會使得渲染資料過大(CPU傳遞給GPU),帶來較大性能損耗,所以可以在游戲中對靜態批處理物件進行一個分塊的處理,將場景中的物件分成多個塊,每個塊的大小可以依據一個經驗值來設定,此時就會出現多個靜態批處理的操作,而不是統一的一個靜態批處理操作,具體的分塊操作取決于具體的專案的場景大小,可以多次測驗得到一個經驗值來進行設定,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/226959.html
標籤:其他
上一篇:多年之后,開個新坑
