(一)unity中的渲染優化技術——————(影響性能的因素、unity中的渲染分析工具)

這個專欄我們會闡述一些unity中常見的優化技術,這些技術基本都是和渲染相關的,例如使用批處理、LOD(Level of Detail)技術等。

遊戲優化不僅是程序員的工作,更需要美工人員在遊戲的美術上進行一定的權衡,例如避免使用全屏的屏幕特效,避免使用計算複雜的shader,減少透明混合造成的overdraw等。這是由程序和美工人員等各部分人員共同參與的工作。

一、移動平臺的特點

和PC平臺相比,移動平臺的GPU架構有很大的不同。由於處理資源等條件的限制,移動設備上的GPU架構專注於盡可能使用更小的帶寬和功能,也由此帶來了許多和PC平臺完全不同的現象。

例如爲了儘可能移除那些隱藏的表面,減少overdraw(即一個像素被繪製多次),PowerVR芯片(通常用於IOS設備和某些Android設備)使用了基於瓦片的延遲渲染(TBDR)架構,把所有的渲染圖像裝入一個個瓦片中,再由硬件找到可見的片元,而只有這些可見片元纔會執行片元着色器。另一些基於瓦片的GPU架構,如Adreno(高通的芯片)和Mati(ARM的芯片)則會使用Early-Z或相似的技術進行一個低精度的深度檢測,來剔除那些不需要渲染的片元。還有一些GPU,如Tegra(英偉達的芯片),則使用了傳統的架構設計,因此在這些設備上,overdraw更可能造成性能的瓶頸。

由於這些芯片架構造成的不同,一些遊戲往往需要針對不同的芯片發佈不同的版本,以便對每個芯片進行更有針對性的優化。尤其是在Android平臺上,不同設備使用的硬件,如圖形芯片、屏幕分辨率等,大相徑庭,這些對圖形優化提出了更高的挑戰,IOS平臺硬件條件則相對統一。

二、影響性能的因素

首先學習如何優化之前,我們得了解影響遊戲性能的因素有哪些。對於一個遊戲來說,它主要使用兩種計算資源:CPU和GPU。它們會互相合作,來讓我們的遊戲可以在預期的幀率和分辨率下工作。其中CPU主要負責保證幀率,GPU主要負責分辨率相關的一些處理。據此我們可以把造成遊戲性能瓶頸的主要原因分成以下幾個方面。

(1)CPU。

過多的draw call。

複雜的腳本或者物理模擬。

(2)GPU。

頂點處理:

過多的頂點。

過多的逐頂點計算。

片元處理:

過多的片元(即可能是由於分辨率造成的,也可能是由於overdraw造成的)。

過多的逐片元計算。

(3)帶寬。

使用了尺寸很大且未壓縮的紋理。

分辨率過高的幀緩存。

對於CPU來說,限制它的主要是每一幀draw call的數目,簡單來說,就是CPU在每次通知GPU進行渲染之前,都需要提前準備好頂點數據(如位置、法線、顏色、紋理座標等)。然後調用一系列API把它們放到GPU可以訪問到的指定位置,最後調用一個繪製命令來告訴GPU進行渲染。而調用繪製命令的時候就會產生一個draw call。過多的draw call會造成CPU的性能瓶頸,這是因爲每次調用draw call時,CPU往往都需要改變很多渲染狀態的設置,而這些操作是非常耗時的。如果一幀中需要的draw call數目過多的話,就會導致CPU把大部分時間都花費在提交draw call的工作上面了。當然其他原因也可能造成CPU的瓶頸,例如物理、布料模擬、蒙皮、粒子模擬等,這些都是計算量很大的操作。

而對於GPU來說,他負責渲染整個流水線。它從處理CPU傳遞過來的模型數據開始,進行頂點着色器、片元着色器等一系列工作,最後輸出屏幕上的每個像素。因此GPU的性能瓶頸和需要處理的頂點數目、屏幕分辨率、顯存等因素有關。而相關的優化策略可以從減少處理的數據規模(包括頂點數目和片元數目)、減少運算複雜度等方面入手

本專欄後續的優化技術有:

(1)CPU優化。

使用批處理技術減少draw call數目。

(2)GPU優化。

1.減少需要處理的頂點數目:

優化幾何體。

使用模型的LOD技術。

使用遮擋剔除(Occlusion)技術。

2.減少需要處理的片元數目:

控制繪製順序。

警惕透明物體。

減少實時光照。

3.減少計算複雜度:

使用Shader的LOD技術。

代碼方面的優化。

(3)節省內存帶寬:

減少紋理大小。

利用分辨率縮放。

開始優化之前,我們首先要知道是哪個步驟造成了性能瓶頸。而這可以利用unity提供的一些渲染分析工具來實現。

三、unity中的渲染分析工具

unity內置了一些工具,幫助我們方便查看和渲染相關的各個統計數據。這些數據可以幫助我們分析遊戲的渲染性能,從而更有針對性地進行優化。在unity5中,這些工具包括了渲染統計窗口(Rendering Statistics Window)、性能分析器(Profiler),以及幀調試器(Frame Debugger)。需要注意的是,在不同的目標平臺上,這些工具中顯示的數據也會發生變化。

3.1渲染統計窗口

這個窗口用來顯示當前遊戲的各個渲染統計變量,我們可以通過在Game視圖右上方的菜單中單擊Stats按鈕來打開它:

可以看出,渲染統計窗口主要包含了3個方面的信息:音頻(Audio)、圖像(Graphics)和網絡(Network)。我們這裏只關注第二個方面,即圖像相關的渲染統計結果。

渲染統計窗口顯示了很多重要的渲染數據,例如FPS、批處理數目、頂點和三角網格的數目等。下表是各個信息數據:

 

unity5的渲染統計窗口相較於之前版本中的有了一些變化,最明顯的區別之一就是去掉了draw call數目的顯示,而添加了批處理數目的顯示。Batches和Saved by batching更容易讓開發者理解批處理的優化結果。當然想要查看draw call的數目等其他更加詳細的數據,可以通過unity編輯器的性能分析器來查看。

3.2性能分析器的渲染區域

可以通過單擊Window->Profiler來打開unity的性能分析器(Profiler)。性能分析器中的渲染區域(Rendering Area)提供了更多關於渲染的統計信息,如圖:

 性能分析器顯示了絕大部分在渲染統計窗口中提供的信息,例如draw call數目、動態批處理/靜態批處理數目、渲染紋理的數目和內存佔用等。

結合渲染統計窗口和性能分析器,我們可以查看與渲染相關的絕大多數重要的數據。性能分析器給出的draw call數目和批處理數目、Pass數目並不相等。並且看起來好像要大於我們估算的數目,這是因爲unity在背後需要進行很多工作,例如初始化各個緩存、爲陰影更新深度紋理和陰影映射紋理等,因此要花費比預期更多的draw call。unity5引入了一個新的工具來幫助我們查看每一個draw call的工作,這個工具就是幀調試器。

3.3幀調試器

這個窗口中,我們可以清楚地看到每一個draw call的工作和結果:

幀調試器的調試面板上顯示了渲染這一幀所需要的所有的渲染事件,比如本例事件數目爲27,而其中包含了24個draw call事件(其他渲染事件多爲清空緩存等)。通過單擊面板上的每個事件,我們可以在Game視圖查看該事件的繪製結果,同時渲染統計面板上的數據也會顯示成截止到當前事件爲止的各個渲染統計數據。

利用這三個工具的幫助下,我們可以獲得很多有用的優化信息。但是很多諸如渲染時間這樣的數據是基於當前的開發平臺得到的,而非真機上的結果。

3.4其他性能分析工具

對於移動平臺上的遊戲來說,我們更希望得到在真機上運行遊戲時的性能數據。這時unity目前提供的各個工具就不能再滿足我們的需求了。

對於Android平臺來說,高通的Adreno分析工具可以對不同的測試機進行詳細的性能分析。英偉達提供了NVPerfHUD工具來幫助我們得到幾乎所有需要的性能分析數據,例如每個draw call的GPU時間,每個每個shader花費的cycle數目等。

對於IOS平臺來說,unity內置的分析器可以得到整個場景花費的GPU時間,PowerVRAM的PVRUniSCo shader分析器也可以給出一個大致的性能評估。Xcode中的OpenGL ES Driver Instrument可以給出一些宏觀上的性能信息,例如設備利用率、渲染器利用率等。但相對於Android平臺,對IOS的性能分析更加困難(工具少)。而且PowerVR芯片採用了基於瓦片的延遲渲染器,因此想要得到每個draw call花費的GPU時間幾乎是不可能的,這時一些宏觀上的統計數據可能更有參考價值。

上面主要概述了一些優化技巧,後面的文章會講述具體的優化方案了。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章