1. 程式人生 > >#遊戲unity-VR場景漫遊#遊戲中的優化(一)

#遊戲unity-VR場景漫遊#遊戲中的優化(一)

基於之前製作專案的經歷教訓——沒有報錯的程式碼合在一起整體執行的時候就執行特別卡,深刻認識到了專案優化的重要性;VR遊戲的流暢度是影響使用者體驗的一個很重要的因素,而且,三區的場景模型也是一個有很多面的模型,執行起來會相當佔資源,為了解決執行卡頓的問題,就必須在程式碼以及系統的搭建中時刻注意對資源的合理使用。
所以,我進行了關於遊戲優化的相關學習,並將好的部落格內容進行了整理。

影響效能的因素

對於一個遊戲來說,有兩種主要的計算資源:CPU和GPU。它們會互相合作,來讓我們的遊戲可以在預期的幀率和解析度下工作。CPU負責其中的幀率,GPU主要負責解析度相關的一些東西。

總結起來,主要的效能瓶頸在於:

CPU
●過多的Draw Calls
●複雜的指令碼或者物理模擬

頂點處理
●過多的頂點
●過多的逐頂點計算

畫素(Fragment)處理
●過多的fragment,overdraws
●過多的逐畫素計算

頻寬
●尺寸很大且未壓縮的紋理
●解析度過高的framebuffer

對於CPU來說,限制它的主要是遊戲中的Draw Calls。那麼什麼是Draw Call呢?如果你學過OpenGL,那麼你一定還記得在每次繪圖前,我們都需要先準備好頂點資料(位置、法線、顏色、紋理座標等),然後呼叫一系列API把它們放到GPU可以訪問到的指定位置,最後,我們需要呼叫_glDraw*命令,來告訴GPU,而呼叫_glDraw*命令的時候,就是一次Draw Call。上面說到過,我們想要繪製圖像時,就一定需要呼叫Draw Call。例如,一個場景裡有水有樹,我們渲染水的時候使用的是一個material以及一個shader,但渲染樹的時候就需要一個完全不同的material和shader,那麼就需要CPU重新準備頂點資料、重新設定shader,而這種工作實際是非常耗時的。如果場景中,每一個物體都使用不同的material、不同的紋理,那麼就會產生太多Draw Call,影響幀率,遊戲效能就會下降。當然,這裡說得很簡單,更詳細的請自行谷歌。其他CPU的效能瓶頸還有物理、布料模擬、粒子模擬等,都是計算量很大的操作。

而對於GPU來說,它負責整個渲染流水線。它會從處理CPU傳遞過來的模型資料開始,進行Vertex Shader、Fragment Shader等一系列工作,最後輸出螢幕上的每個畫素。因此它的效能瓶頸可能和需要處理的頂點數目的、螢幕解析度、視訊記憶體等因素有關。總體包含了頂點和畫素兩方面的效能瓶頸。在畫素處理中,最常見的效能瓶頸之一是overdraw。Overdraw指的是,我們可能對螢幕上的畫素繪製了多次。

優化技術

  • 頂點優化
    • 優化幾何體
    • 使用LOD技術
    • 使用遮擋剔除技術
  • 畫素優化
    • 控制繪製順序
    • 警惕透明物體
    • 減少實時光照
  • CPU優化
    • 減少Draw Calls
  • 頻寬優化
    • 減少紋理大小
    • 利用縮放
      以下進行詳細介紹。

頂點優化

優化幾何體

在建模時,要有意識的減少三角面片的數量
三維軟體裡更多地是站在我們人類的角度理解頂點的,即我們看見的一個點就是一個。而Unity是站在GPU的角度上,去計算頂點數目的。而在GPU看來,看起來是一個的很有可能它要分開處理,從而就產生了額外的頂點。這種將頂點一分為多的原因,主要有兩個:一個是UV splits,一個是Smoothing splits。而它們的本質其實都是因為對於GPU來說,頂點的每一個屬性和頂點之間必須是一對一的關係。UV splits的產生,是因為建模時,一個頂點的UV座標有多個。例如之前的立方體的例子,由於每個面都有共同的頂點,因此在不同面上,同一個頂點的UV座標可能發生改變。這對於GPU來說,這是不可理解的,因此它必須把這個頂點拆分成兩個具有不同UV座標的定頂點,它才甘心。而Smoothing splits的產生也是類似的,不同的時,這次一個頂點可能會對應多個法線資訊或切線資訊。這通常是因為我們要決定一個邊是一條Hard Edge還是Smooth Edge。Hard Edge通常是下面這樣的效果(注意中間的摺痕部分):
這裡寫圖片描述
這裡寫圖片描述
而如果觀察它的頂點法線,就會發現,摺痕處每個頂點其實包含了兩個不同的法線。因此,對於GPU來說,它同樣無法理解這樣的事情,因此會把頂點一分為二。而相反,Smooth Edge則是下面的情況:
這裡寫圖片描述
這裡寫圖片描述
對於GPU來說,它本質上只關心有多少個頂點。因此,儘可能減少頂點的數目其實才是我們真正對需要關心的事情。因此,最後一條優化建議就是:移除不必要的Hard Edge以及紋理銜接,即避免Smoothing splits和UV splits。

LOD技術

LOD是對模型建立了一個模型金字塔,根據攝像機距離物件的遠近,選擇使用不同精度的模型。它的好處是可以在適當的時候大量減少需要繪製的頂點數目。它的缺點同樣是需要佔用更多的記憶體,而且如果沒有調整好距離的話,可能會造成模擬的突變。一般是在解決執行時流暢度的問題,採用的是空間換時間的方式。

  1. 準備3組模型,高精度模型,中精度模型,和低精度模型,並按照複雜程度自高向低的為模型命名
    這裡寫圖片描述

  2. 定義一個空物件,新增LODGroup元件,如圖所示:
    這裡寫圖片描述

  3. 分別將剛剛準備好的三種不同精度的模型,拖拽到空物件的LODGroup元件的各個級別上。首先給LOD元件的“LOD 0”(LOD 0 表示攝像機最近距離顯示)新增對應的模型。(LOD 0 對應高精度模型,然後拖拽到Add上面即可)如圖所示:
    這裡寫圖片描述

  4. 在LOD元件新增模型的過程中會彈出如圖所示的提示資訊,表明要把新增的模型作為LODGroup元件所屬物件的子物體,單擊”Yes,Reparent”按鈕即可

  5. 為使構造的LOD遊戲物件顯示得更加自然,需要把LOD下的三個子物體進行”對齊“處理。(將其相對於父物體的座標置為0)
    這裡寫圖片描述
    最後在Scenes檢視中,拖動攝像機分別近距離與遠距離觀察模型的變化即可。

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

附上不錯的教程 基礎

接下來的內容,會在下一篇中進行整理。