天天看點

Unity渲染優化中文翻譯(一)——定位渲染問題

     轉載請标明出處 http://www.cnblogs.com/zblade/

   最近有一點個人的時間,嘗試一下自己翻譯一下英文的 Optimizing graphics rendering in Unity Games,

這兒附上英文連結:

  個人英文水準有限,unity圖像學知識也是入門,希望通過這次翻譯能增進自己的圖形學知識,若有錯誤,歡迎各位大神指點,讓我也學習進步,謝謝。

一、介紹

    本文主要學習在Unity進行一幀的渲染的時候,觀察到的場景背後的運作原理,在渲染的時候會有什麼樣性能問題發生以及如何解決這些渲染相關的問題。

  在開始閱讀這篇文章之前,首先需要知道對于渲染問題是沒有萬能的解決之法的。渲染的結果受到遊戲中衆多因素的影響,同時也極其依賴于遊戲所運作的硬體條件和作業系統。最重要的一點,是要記住我們需要通過分析,實驗和測試,嚴密的分析測試結果來解決渲染性能問題。

 本文主要分析常見的渲染問題并提供相應問題的解決辦法及其連結,并不能完全概括渲染的問題,是以本文主要旨在提供解決的思路并提供一些較為有效的查找辦法的途徑。

二、渲染的簡單介紹

    在開始本文之前,讓我們快速的回顧一下在Unity的一幀渲染中發生的事情。了解下面的一些概念和關系對于解決渲染性能問題有較大的幫助。

注意:在全文中我們會使用"object"來代表遊戲中需要被渲染的物體,任何帶有渲染元件的物體都可以被稱為object。

 從最基本的角度看,渲染過程的元件可以分為:

    1)CPU,主要計算出需要被渲染的對象和渲染的方式;

    2)GPU,CPU将渲染指令發送給GPU

    3)GPU根據CPU的渲染指令進行渲染工作

 本文接下來會詳細介紹這幾步流程,現在隻需要熟悉這幾個關鍵詞彙并了解其在渲染過程中所扮演的角色。

 渲染管道常常被這生動的用來描述渲染的過程,高效的渲染過程就是保持資訊的流動。CPU在每幀的渲染過程中的工作主要包括:

  1)CPU檢查場景中的object是否需要被渲染。一個object隻有滿足一定的條件才可以被渲染,例如它的部分模型處于相機的視角範圍内 View frustrum。被剔除的object是不會被渲染的,更多關于相機視角和視角剔除的資訊可以點選這裡

  2)CPU收集需要被渲染的object并将其排序為渲染指令(Draw calls)。一個DC主要包含一個網格的資料和其渲染方式,例如其中哪個貼圖需要被使用。在通常情況下,使用相同的DC的objects會被合并,這種合并不同渲染objects的操作就是批處理(batching)。

  3)CPU對每個DC中的資料進行批處理打包,有時打包的結果有時更多的包含的是資料而不是DC,但是這對渲染影響不大,是以本文并不考慮這些情況。

  對于每個包含DC的打包指令,CPU必須進行以下處理:

  1) CPU發送一個指令改變目前的渲染狀态(render state)。這個指令叫做 SetPass call,主要用來告訴GPU下一個被渲染的網格的渲染設定,該指令也隻有在下一個渲染網格的渲染設定和目前的設定不同的時候會被發送。

  2)CPU發送DC給GPU,DC指令主要操作GPU采用最近的SetPass Call 設定來對特定的網格進行渲染。

.在一些情況下,在一個batch中會有多個pass(shader中的一部分代碼),如果一個pass中要求新的渲染狀态(render state),那麼CPU就會發送一個新的SetPass指令給GPU,然後重新發送DC指令。

  與此同時,GPU需要進行如下操作:

  1)GPU根據指令的順序處理渲染任務。

  2)如果目前的任務是SetPass Call,那麼更新目前的渲染狀态。

  3)如果目前任務為DC,GPU就渲染網格。 根據shader代碼中的不同步驟進行渲染。該部分的渲染較為複雜,在此并不做深入闡述,但是了解shader中的 vertex shader有利于了解GPU是如何處理網格中的頂點資料,了解shader中的 fragment shader有利于了解GPU是如何繪制每個單獨的像素點。

  4)這個過程會重複的進行直到CPU中發送過來的渲染指令都被處理完。  

  在了解了Unity在進行一幀的渲染中的操作後,現在我們考慮在渲染中的一些問題。

  1、渲染問題的分類

  對于渲染,有一個關鍵點是:CPU和GPU必須在渲染的一幀中完成各種的任務,如果任何一個花費較長時間來完成,則會造成一幀的渲染延遲。

  渲染的問題主要有兩個基本的因素。第一因素是低效的渲染管道,如果在渲染管道過程中某個或者多個步驟消耗較長時間就會造成渲染管道的低效,進而中斷資料流,這也被稱為渲染瓶頸。第二個因素是渲染管道中資料過多,即使是最高效的渲染管道在每幀的渲染進行中也有資料量大小的限制。

  如果渲染問題來自于CPU在計算渲染任務時耗時過長,則将其稱為 CPU bound, 如果渲染問題來自于GPU渲染耗時過長,則将其稱為 GPU bound。

  2、了解定位渲染問題

  在我們進行任何渲染改進之前,可以利用分析工具來了解定位造成渲染問題的原因。不同的問題有不同的解決辦法,同時我們需要測量我們的改進結果。解決渲染性能問題是一個平衡的操作,提升一方面的性能會對另一方面的性能造成相反的效果。

  我們将利用兩種unity中的工具來定位渲染性能問題:Profiler window 和 Frame Debugger.

  The Profiler window

  利用profiler window 我們可以檢視到遊戲運作時各個方面的實時資料,包括記憶體使用,渲染管道和腳本的性能。如果你對profiler window還不是很熟悉,可以點選此處this page of the Unity Manual,使用文檔:文檔

  The Frame Debugger

  利用Frame Debugger可以了解每幀的渲染操作及其詳細的渲染資訊,比如每個DC中渲染的是什麼,每個DC的shader屬性,GPU接收到的渲染指令順序等。利用渲染資訊可以幫助我們了解到遊戲中的渲染情況進而提升遊戲的性能。

  如果你對Frame Debugger不是很了解,可以點選此處:this page of the Unity Manual ,視訊展示點選此處:視訊展示

  查找造成渲染性能問題的原因

   在我們嘗試改進渲染問題的時候,我們必須确定遊戲運作較慢的原因是由渲染問題造成,如果遊戲運作較慢來自于遊戲腳本運作複雜則優化渲染無濟于事,可以通過此處來确定是否由于渲染造成遊戲運作較慢:點選此處

   一旦我們确定遊戲運作較慢來自于渲染,則需要确定是由于CPU還是GPU,不同的問題有不同的解決辦法,是以在解決問題前定位問題非常重要,如果你不确定渲染問題來自于CPU還是GPU,可以點選:點選此處

   在定位渲染問題來自于CPU還是GPU後,下面詳細介紹各自的解決辦法,參看下一篇文章。