Render- 關於Unity渲染方面的優化(下)

Render- 關於Unity渲染方面的優化(下)

來自專欄 Unity

如果渲染問題是由GPU瓶頸(GPU bound)引起的

首先,大多數GPU的性能瓶頸問題主要來自於 填充率(fill rate),尤其在移動設備上,其次

內存帶寬(memory bandwidth)頂點處理(vertex processing)也會導致GPU性能瓶頸。

Fill rate

填充率,與GPU每秒可以渲染到屏幕的像素數量有關。如果我們的遊戲受到填充率的限制,那麼說明我們的遊戲每一幀輸出到屏幕的像素數量超過了GPU的承載限度。

要檢查是否是 填充率 導致的GPU瓶頸方式很簡單,

  1. 運行遊戲,在Profiler窗口觀察GPU的效率
  2. 減小Game窗口的尺寸達到降低窗口解析度的效果
  3. 再運行遊戲,觀察GPU的效率,如果遊戲的表現提升了,那麼很可能就是填充率導致的問題。

確定了是填充率導致的,我們可以通過以下幾個方面來進行優化:

片元著色器(Fragment Shader)是shader代碼塊中告訴GPU該如何逐像素渲染的部分,這部分代碼是由GPU來執行的,並且每一個像素都會被計算。複雜的片元著色器代碼常常是引起填充率問題的根源。

  • 如果我們的遊戲使用的是內置shader,我們應該儘可能使用最簡單的且最優的shader來達到我們的預期效果。比如,unity的針對移動平台的內置shader,它經過一定的優化。這類shader不但適用移動平台,也適用於其他平台的任何項目。在不失預期效果的前提下,使用」mobile」類的shader是最佳選擇。
  • 如果被渲染對象使用的是unity的 標準shader(standard shader),要知道 unity是基於它當前所在的材質面板中的設置來進行編譯。而且只有當該材質被使用時shader才被編譯。這意味著,通過移除一些材質上的特性比如 detailed maps 會導致片元著色器的計算複雜度降低,即提升性能表現。當然,實際項目中,在不失預期效果的前提下,我們可以通過改變材質的設置來測試是否提升了GPU性能。

Standard Shader效果

  • 如果使用 自定義shader,我們應該儘可能去優化它。這裡是一些自定義shader的優化方案。

Overdraw 是當同一個像素被進行多次繪製導致的一種現象。這種現象會產生比較嚴重的填充率問題。要理解overdraw, 我們必須要知道unity場景中渲染對象的渲染順序。一個渲染對象的shader決定了它被渲染順序,通過在shader中設置 渲染隊列(render queue)這個屬性來改變引擎對其渲染對象的渲染順序。在不同渲染隊列中的對象也是按照不同的順序進行排列。比如,unity在 幾何體隊列(Geometry Queue)中,是按照 從前到後(front-to-back)的順序來對幾何體來進行繪製,這樣可以最小化overdraw,但是在透明隊列(Transparent Queue)中,是按照 從後到前(back-to-front)的順序來實現屏幕上物體的透明效果。Overdraw的優化是一個比較複雜的話題,沒有一個萬能的解決方案,但是我們可以通過減少那些無法自動排列的渲染對象的重疊(overlapping)是關鍵。我們最好從unity的Scene 試圖著手研究,在我們編輯器下的Draw Mode里可以讓我們看到當前場景中的overdraw情況。

Scene窗口的Overdraw選項

這可以幫我們定位哪些地方可以減少overdraw。其實,產生overdraw的始作俑者主要是透明的材質、未優化的粒子 以及 重疊的UI元素,具體方法這裡就不展開了,對overdraw如何優化的小夥伴可以點擊 這裡

後處理(PostProcessing)

後處理也是導致填充率問題的關鍵,尤其是我們使用了超過一種後處理。如果在項目中我們遇到了後處理的問題,我們需要通過進行不同的設置和測試來達到優化的目的(諸如 Bloom等後處理效果)。如果同一個相機上有不止一種後處理效果,這會導致許多pass通道的使用,引起性能瓶頸,這種情況下最好將shader代碼中後處理的部分合併到一個pass通道下。如果這樣做還是沒用,那可能就要考慮不使用這些效果,尤其是在一些低端機上。

內存帶寬(Memory bandwidth)

內存帶寬指的是GPU可以讀取和寫入的速率。如果遇到內存帶寬的問題,常常是由於我們使用了非常大的紋理以至於GPU無法快速的處理它。

如果檢查是否是內存帶寬的問題,我們可以參考以下步驟:

  1. 運行遊戲並關注GPU的性能情況
  2. 減少紋理的精度,並且可以在Quality Settings中進行相關設置。
  3. 再次運行遊戲並且關注GPU的性能情況

如果是內存帶寬的問題,我們需要減小紋理佔用的顯存。關於如何優化我們的紋理:

紋理壓縮(Texture compression)是一種可以大大減少存儲在磁碟上或者內存上的紋理大小的方式。Unity提供許多種不同的紋理壓縮的格式以及其對應的設置,來幫助設置紋理的大小。

紋理壓縮的格式(Texture Type)

Mipmaps是一種低解析度的紋理貼圖。當場景中的渲染物體距離相機比較遠時,我們可以通過Mipmaps選項來緩解GPU的內存帶寬。

Mipmaps勾選框

將Scene場景下的繪製模式改成Mipmaps可以幫助我們知道場景中哪些對象的紋理可以使用MipMaps。

頂點處理(Vertex processing)

頂點處理是指GPU在渲染流程中要對網格的每一個頂點進行計算。頂點處理工作的開銷主要體現在兩個方面:需要被渲染的頂點數量 以及 每一個頂點的計算量。

如果GPU的問題既不是由填充率或 內存帶寬引起的,那麼很可能就是由於頂點處理工作引起的。

我們可以通過以下方式來對頂點數量以及頂點計算量進行優化:

  • 首先我們需要把目標瞄準減少沒有意義的網格頂點。即在遊戲中,玩家幾乎看不到細節的網格頂點 或者 在生成模型時導致的頂點過多,這些都會無形中給GPU造成多餘的開銷。在不影響視覺效果的前提下,我們應當儘可能使用頂點數較低的網格。
  • Unity還提供了法線貼圖(normal mapping),這類紋理貼圖是用來實現一種幾何上的視錯覺,讓你對網格產生一種立體感。儘管這種技術會對GPU產生一定的消耗,但是它在很多場合收益大於開銷。
  • LOD技術(Level of detail),它是根據網格距離相機的遠近程度來調整模型,相當於是建立一個模型金字塔,根據相機距離模型的位置,對使用的模型進行切換,從而在離相機較遠時減少頂點的數量。具體請點擊 這裡
  • 頂點著色器是用來告訴GPU該怎麼繪製每個頂點。減少我們著色器中頂點部分的計算量也可以有效的提升GPU性能。

文章轉自:

Unity - Optimizing graphics rendering in Unity games?

unity3d.com圖標
推薦閱讀:

【《Real-Time Rendering 3rd》 提煉總結】(六) 第七章 · 高級著色:BRDF及相關技術
【《Real-Time Rendering 3rd》提煉總結】完結篇:系列合集電子書PDF下載&實時渲染知識網路圖譜&新系列預告
Diffuse and Specular Reflection (3)
Fresnel Effect (8)
《全局光照技術》前10章終極目錄首次公布

TAG:Unity遊戲引擎 | 渲染 | 性能 |