UnityShader學習 渲染優化技術(分析)

2021-10-05 10:08:15 字數 4071 閱讀 6188

對問題認識不清以及過度優化往往會讓事情變得更加複雜,產生更多的程式錯誤。然而,如果我們在遊戲開發過程中從來都沒有考慮優化,那麼結果往往是慘不忍睹的。乙個正確的做法是,從一開始就把優化當成是遊戲設計中的一部分。和pc相比,移動裝置上的gpu有著完全不同的架構設計,它能使用的頻寬、功能和其他資源都非常有限。這要求我們需要時刻把優化謹記在心,才可以避免等到專案完成時才發現遊戲根本無法在移動裝置上流暢執行的結果。

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

和pc平台相比,移動平台上的gpu架構有很大的不同。由於處理資源等條件的限制,移動裝置上的gpu架構專注於盡可能使用更小的頻寬和功能,也由此帶來了許多和pc平台完全不同的現象。例如,為了盡可能移除那些隱藏的表面,減少overdraw(即乙個畫素被繪製多次), powervr晶元(通常用於ios裝置和某些android裝置)使用了基於瓦片的延遲渲染(tiled-based deferred rendering, tbdr)架構,把所有的渲染影象裝入乙個個瓦片(tile)中,再由硬體找到可見的片元,而只有這些可見片元才會執行片元著色器。另一些基於瓦片的gpu架構,如adreno(高通的晶元)和mali(arm的晶元)則會使用early-z或相似的技術進行乙個低精度的的深度檢測,來剔除那些不需要渲染的片元。還有一些gpu,如tegra(英偉達的晶元),則使用了傳統的架構設計,因此在這些裝置上,overdraw更可能造成效能的瓶頸。

由於這些晶元架構造成的不同,一些遊戲往往需要針對不同的晶元發布不同的版本,以便對每個晶元進行更有針對性的優化。尤其是在android平台上,不同裝置使用的硬體,如圖形晶元、螢幕解析度等,大相徑庭,這對圖形優化提出了更高的挑戰。相比與android平台,ios平台的硬體條件則相對統一。讀者可以在unity手冊的ios硬體指南中找到相關的資料。

對於乙個遊戲來說,它主要需要使用兩種計算資源:cpu和gpu。它們會互相合作,來讓我們的遊戲可以在預期的幀率和解析度下工作。其中,cpu主要負責保證幀率,gpu主要負責解析度相關的一些處理。

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

而對於gpu來說,它負責整個渲染流水線。它從處理cpu傳遞過來的模型資料開始,進行頂點著色器、片元著色器等一系列工作,最後輸出螢幕上的每個畫素。因此,gpu的效能瓶頸和需要處理的頂點數目、螢幕解析度、視訊記憶體等因素有關。而相關的優化策略可以從減少處理的資料規模(包括頂點數目和片元數目)、減少運算複雜度等方面入手。

據此,我們可以把造成遊戲效能瓶頸的主要原因及相應應對措施分成以下幾個方面:

(1)cpu

(2)gpu

片元處理:—>減少需要處理的片元數目(控制繪製順序、 警惕透明物體、減少實時光照)。

(3)頻寬

unity內建了一些工具,來幫助我們方便地檢視和渲染相關的各個統計資料。這些資料可以幫助我們分析遊戲渲染效能,從而更有針對性地進行優化。在unity 5中,這些工具包括了渲染統計視窗(rendering statisticswindow)、效能分析器(profiler),以及幀偵錯程式(framedebugger)。需要注意的是,在不同的目標平台上,這些工具中顯示的資料也會發生變化。

(1)渲染統計視窗(rendering statisticswindow)

unity 5提供了渲染統計視窗(renderingstatistics window)來顯示當前遊戲的各個渲染統計變數,我們可以通過在game檢視右上方的選單中單擊stats按鈕來開啟它。從圖中可以看出,渲染統計視窗主要包含了2個方面的資訊:音訊(audio)、影象(graphics)。我們這裡只關注第二個方面,即影象相關的渲染統計結果。

渲染統計視窗中顯示了很多重要的渲染資料,例如fps、批處理數目、頂點和三角網格的數目等。下表列出了渲染統計視窗中顯示的各個資訊。

(2)效能分析器的渲染區域

我們可以通過單擊window -> profiler來開啟unity的效能分析器(profiler)。效能分析器中的渲染區域rendering area)提供了更多關於渲染的統計資訊,下圖是某個場景的渲染分析結果。

效能分析器顯示了絕大部分在渲染統計視窗中提供的資訊,例如,綠線顯示了批處理數目、藍線顯示了pass數目等。最下方的視窗還給出了許多其他非常有用的資訊,例如,draw call數目、動態批處理/靜態批處理的數目、渲染紋理的數目和記憶體占用等。結合渲染統計視窗和效能分析器,我們可以檢視與渲染相關的絕大多數重要的資料。乙個值得注意的現象是,效能分析器給出的draw call數目和批處理數目、pass數目並不相等,並且看起來好像要大於我們估算的數目,這是因為unity在背後需要進行很多任務作,例如,初始化各個快取、為陰影更新深度紋理和陰影對映紋理等,因此需要花費比「預期」更多的drawcall。

(3)幀偵錯程式

我們可以通過window -> frame debugger來開啟它。在這個視窗中,我們可以清楚地看到每乙個draw call的工作和結果。幀偵錯程式的除錯面板上顯示了渲染這一幀所需要的所有的渲染事件,在本例中,事件數目為30,。通過單擊面板上的每個事件,我們可以在game檢視檢視該事件的繪製結果,同時渲染統計面板上的資料也會顯示成截止到當前事件為止的各個渲染統計資料。

unity的渲染統計視窗、分析器和幀偵錯程式這3個利器的幫助下,我們可以獲得很多有用的優化資訊。但是,很多諸如渲染時間這樣的資料是基於當前的開發平台得到的,而非真機上的結果。我們仍然需要一些外部的效能分析工具的幫助。

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

對於android平台來說,高通的adreno分析工具可以對不同的測試機進行詳細的效能分析。英偉達提供了nvperfhud工具來幫助我們得到幾乎所有需要的效能分析資料,例如,每個draw call的gpu時間,每個shader花費的cycle數目等。

對於ios平台來說,unity內建的分析器可以得到整個場景花費的gpu時間。powervram的pvrunisco shader分析器也可以給出乙個大致的效能評估。xcode中的opengl es driver instruments可以給出一些巨集觀上的效能資訊,例如,裝置利用率、渲染器利用率等。但相對於android平台,對ios的效能分析更加困難(工具較少)。而且powervr晶元採用了基於瓦片的延遲渲染器,因此,想要得到每個draw call花費的gpu時間是幾乎不可能的。這時,一些巨集觀上的統計資料可能更有參考價值。

一些其他的效能分析工具可以在unity的官方手冊(中找到。當找到了效能瓶頸後,我們就可以針對這些方面進行特定的優化。

asset store中也有一些不錯的效能分析工具(非渲染方面),如build report toolpoolmanagercruncher等。

unity Shader前向渲染

unity shader前向渲染記錄,先說原理,後附 1 前向渲染的原理 兩個pass,乙個basepass主要負責 乙個addpass主要負責 2 對光源處理方式分類 unity在渲染每乙個物體之前都會根據光源的強度,顏色,距離物體的遠近以及光源對該物體的影響程度對場景中的所有光源進行乙個重要度排...

Unity Shader學習筆記 渲染流水線

渲染流程分為3個階段,應用階段 幾何階段 光柵化階段 這個階段由cpu實現 開發者對應用階段有絕對的控制權,開發者將場景資料準備好,例如攝像機的位置,場景包含了哪些模型。其中,通常為了提高渲染的效率,開發者會將不可見的物體剔除,稱之為粗粒剔除。最後我們會設定好模型的渲染狀態 例如材質,紋理,使用的s...

UnityShader 渲染流水線

渲染具體流程 幾何階段 光柵化階段 渲染流水線的最終目的在於生成或者說是渲染一張紋理,即我們在螢幕上看到的所有效果。它的輸入是乙個虛擬攝像機 一些光源 一些shader以及紋理等。渲染流程分為3個階段 應用階段 幾何階段 光柵化階段。圖中,綠色表示該階段是完全可程式設計控制的,黃色表示可以配置但不是...