如何有效提高Unity Gear VR遊戲性能

http://www.vr186.com/vr_news/vr_technical_area/1093.html
html

好的,因此你決定用 Unity 來作一個 VR 遊戲,並選定了三星 Gear vr 爲你的目標平臺。作好以後,打開應用,在設備上執行文件再容易不過 – 但有個問題,幀率實在過低。視野邊上有閃爍的黑邊出現,感受好像有誰往攝像機操做員的肚子上踢了幾腳。你據說過保持穩定的幀率有多重要,如今你明白爲何了 – 在虛擬現實中,任何低於每秒60幀的東西不只看起來很差,讓人難受纔是最糟糕的。你的高端上檔臺式機能把這個遊戲運行到每秒1000幀,但機箱發出的聲音像飛機引擎同樣,並且……風扇發動時機箱好像真的升起來一點了!如今你要作的就是把你的大做針對移動芯片好好地優化一下。這個系列的文章針對的就是這個問題。緩存

第一部分: 運行環境以及高效率VR應用的一些特徵

這並非關於 Gear vr 的一個優化大全,更像是一個快速入門吧。在這第一貼中咱們將先討論下 Gear vr的硬件以及設計良好的移動 VR 應用的一些特色。以後將會着重講述如何針對你的應用來提高表現。這篇文章主要針對 Unity,由於這是目前 Gear VR 開發中的主流引擎。可是,這些概念對於其它引擎來講也是能夠適用的。多線程

瞭解你的硬件

在把你的項目大卸八塊尋找其低效之處以前,最好先花點時間思考下當下移動手機的一些表現特徵。總的來講,移動圖形管線基於一個很快的 CPU ,經過一個很慢的總線和/或內容控制器來和一個很快的 GPU 鏈接,還須要一個形成不少開銷的 OpenGL ES 驅動。Gear VR 在三星 Note4 和 S6 上運行。這兩個產品線表明了幾種不一樣的硬件規格:併發

  • Note 4 的核心有兩種。在北美和歐洲售賣的版本基於高通的驍龍芯片(SnapDragon 805),而在韓國和亞洲一些其它地區的基本都是三星本身的獵戶座芯片(Exynos 5433)。驍龍芯片是四核 CPU 規格,而獵戶座有八核,這兩個核心分別對應兩種 GPU: Adreno 420 以及 Mali-T760。
  • Note 4 又被最近的谷歌分紅兩種系統。分別是安卓 4.4.4 (KitKat) 和 Android 5 (Lollipop)。目前基本上世界上的獵戶座的 Note4 都運行安卓5.0了(看來我給世界拖後腿了)。
  • S6 則都只有一種核心:Exynos 7420 (圖形芯片是 Mali-T760M8)。還有另外一個版本的 S6,S6Edge,但它們除了外形不同之外裏面都是同樣的。
  • 全部的 S6 都是安卓5.0棒棒糖系統。

看起來好複雜是吧!沒事,它們全部的性能和表現其實都很接近(除了一種情況,最下面的注意事項裏會說),若是你能在某個設備上跑得不錯,在其它上面應該也不會有生命問題。異步

和多數移動芯片同樣,它們的 3D 圖形表現方面的屬性都比較穩定可靠。所以,這裏有一些廣泛的可能讓你的項目跑得很差的緣由(按嚴重順序排列):編輯器

  • 場景須要獨立的渲染器(好比陰影和反射)(CPU/GPU開銷)
  • 綁定 VBO 來進行繪製調用(CPU/驅動開銷)
  • 透明,多通道渲染,每像素照明以及其它的像素效果(GPU/IO 開銷)
  • 大型紋理加載,blits,以及各類類型的內存開銷(IO/內存控制開銷)
  • 蒙皮動畫(CPU開銷)
  • Unity 垃圾回收開銷(CPU開銷)

另外一方面來講,這些設備有着比較大的內存,能夠描畫比較多的多邊形。Note4 和 S6 都有着 2560×1440 的分辨率,但默認狀況下咱們通常只渲染 1024×1024 的紋理分辨率來節約填充率。ide

瞭解你的VR環境

VR 渲染讓硬件的表現受到最嚴苛的考驗,由於每一幀都必須給雙眼繪製共兩次。在 Unity 4.6.4p3 和 5.0.1p1 裏,意味着每一個繪製調用都被執行了兩次,每一個網格被繪製了兩次,每一個紋理被裝訂了兩次。此外還有少許的開銷被分配給了最終的畸變和時間穿越(2ms的預算)上。雖然咱們期待將來硬件的表現以及程序的流程會愈來愈好,但目前就是得每幀畫兩次。這意味着相較於普通的遊戲,VR 遊戲的開銷要多幾乎一倍。函數

而基於這些特性,如下是一些比較靠譜的 Gear VR 應用渲染目標。性能

提高unity gear vr遊戲性能2
這一幀大概有30000個多邊形和40個繪製調用

  • 每幀 50 – 100 個繪製調用
  • 每幀 50k – 100k 個多邊形
  • 紋理貼圖越少越好(但每一個能夠很大)
  • 腳本執行時間在 1 ~ 3 毫秒之內 (Unity Update())

注意這些不是硬性規範,只是咱們的經驗之談。測試

另外注意 Oculus Mobile SDK 還引進了一個給 CPU 和 GPU 節流降頻的 API 來控制熱量和電池消耗(查閱使用樣例 OVRModeParams.cs)這些方式讓你能夠選擇對於在某個場景下,控制 CPU 和 GPU 的開銷。比方說,若是在繪製調用的提交上出了問題,你讓 CPU 升頻(同時讓 GPU 降頻)可能能提高總體的幀率。若是你忽視這些作法,你的應用可能會被迫運行在降頻的環境下,所以你最好多花點時間在這上面。

最後,Gear VR 也擁有 Oculus 的異步時間穿越(Asynchronous TimeWarp)技術。TimeWarp 能在程序變慢時基於最近的頭部姿態信息來獲得接下來的幀畫面。它經過頭部信息來扭曲上一幀的畫面,能幫助你即使在偶爾丟失幾幀時也能有流暢的體驗,但絕對不是一個讓你把應用隨意運行在60幀每秒如下的藉口。若是你左右搖擺腦殼時能看到眼角黑色的色塊,就說明你的遊戲已經慢到 TimeWarp 沒有足夠的幀畫面來填補這些黑色空白了。

爲性能表現而設計

作出表現良好的應用就是爲了表現良好而去設計,而這意味着圍繞移動 GPU 的一些特性來設計你的美術資源。

準備事項

在開始以前,先確保你的 Unity 項目的設定都已經爲最高表現設定好了。特別的,是肯定以下值的設定:

  • 靜態批處理(Static batching)
  • 動態批處理(Dynamic batching)
  • GPU 蒙皮(GPU skinning)
  • 多線程渲染(Multithreaded Rendering)
  • 默認方向到地平左邊(Default Orientation to Landscape Left)

批處理

如今咱們知道的是,通常來講繪製調用數量是 Gear VR 應用中最佔用資源的方面,那麼優化的第一步就是在藝術層面上作出一些設計,讓程序在最終實現時調用越少的繪製命令越好。一個繪製調用就是對 GPU 的一個命令,讓它繪製一個網格或者網格的一部分。而這個命令最佔用資源的部分實際上是網格的選擇自己。每一次當程序決定繪製一個新網格時,網格在被提交給 GPU 以前必須先被驅動進行處理。着色器必須被彈回,可能會發生一些格式的轉化等等;而這些過程在每次一個新的網格被選中後都會發生,並佔用了最大的開銷。

但這也一樣意味着,每次一個網格(或者更具體一點,一個頂點緩衝區對象VBO)被選中後,只須要佔用這一次開銷,就能使用屢次。只要沒有新的網格(或者紋理、着色器)被選中,當前狀態會一直存在於驅動緩存中並能夠進行反覆使用。爲了利用這個特性,咱們能夠將多個網格整合進一個大的頂點陣列中,並經過 VBO 進行單獨繪製。咱們付出一次選擇的代價後,就能夠從這個對象內包含的多個網格進行調用而不會提升系統開銷。這個方式被稱做爲批處理(Batching),比起爲每個不一樣的網格建立 VBO 要快得多,也是針對繪製調用進行優化的基礎。

單個 VBO 中的全部網格必須享有一樣的材質,才能進行批處理的整合:一樣的紋理、着色器以及着色器參數。爲了更高效地在 Unity 中利用批處理,咱們還得更進一步:對象必須有一樣的材質對象指針。爲此,這裏有一些參考規則:

提高unity gear vr遊戲性能3
紋理集合/圖譜

  • 紋理集合(Macrotexture / Texture Atlases):經過將盡量多的模型映射到少數幾個大的紋理集合中來達到儘量少的紋理數量。
  • 靜態旗幟(Static Flag): 將全部不會移動的對象在 Unity 的 Inspector 中標記爲靜態。
  • 材質訪問:當心訪問 Renderer.material。這個操做會複製材質並返回給你復件,致使對象被排除在批處理以外(由於材質指針變成獨特的了)。請使用 Renderer.sharedMaterial。
  • 確保批處理是開啓的:在玩家設定(看下面)中確保靜態批處理和動態批處理都被開啓了。

Unity 提供兩種將網格批處理的方式:靜態批處理和動態批處理。

靜態批處理

一旦你把某個網格標記成靜態,這意味着你告訴 Unity 這個對象永遠不會移動、變形或者縮放等。Unity 會基於這一點來自動將全部享用一樣材質的網格整合成一個大的。在某些狀況下,這將是很好的優化;不只減小了繪製調用數量,Unity 也把變形操做變成了頂點的位置選擇,這樣在運行時就不須要變形了。在一個場景內,越多的部分能被標記成靜態越好。要記得只有一樣材質的才能被整合在一塊兒哦!

但須要注意的是,靜態批處理生成了新的一個大網格,有可能致使最終的應用容量變得很大。通常來講對於 Gear VR 開發者問題不大,但若是你的應用裏有不少不一樣場景,每一個場景都有不少靜態網格,那麼最終佔用可能就會比較大。因此另外一個選項就是在運行時使用StaticBatchingUtility.Combine來生成批處理網格,而不會讓你的應用變得太大(但你得付出一個一次性的 CPU 大量開銷以及必定的內存佔用的代價)。

最終,當心你的 Unity 版本,確認是否支持靜態批處理(看最後的注意事項)。

動態批處理

只要共享一樣的材料,Unity 也能把那些並無標記爲靜態的網格進行批處理。只要你把動態批處理選項打開,剩下的基本就不太用管了。對每幀都進行批處理會對計算性能形成一些開銷,但通常來講對於總體性能表現老是會有提高。

批處理的其它問題

固然,還有其它一些狀況也要當心。好比給物體繪製陰影啦,其它須要給物體轉換狀態的多通道着色器(Multi-pass shader)啦,都會讓批處理出現問題。多通道着色會讓網格被提交屢次,針對 Gear VR 時務必要當心處理。逐像素光照(Per-pixel lighting)也有着相似的效果:使用 Unity4 裏默認的擴散着色器(Diffuse Shader),網格會在每次被光線接觸時從新提交一次,很快會把你的繪製調用數和多邊形數耗光。若是你須要逐像素光照,能夠試着在質量設置窗口中的併發光照總數設置爲一。最近的光線會被逐像素渲染,而周遭的光線會經過球面調和函數(Spherical Harmonics)來計算得出。更好的方式是放棄逐像素光照,採用光照探針。另外要注意的是批處理不支持蒙皮網格。透明對象必需要按某種順序來進行繪製因此很難被進行恰當的批處理。

不過,你仍是能夠在編輯器中測試、調校批處理的。不管是在 Unity Profiler (Unity Pro 纔有) 仍是遊戲窗口的統計欄中,都能顯示當前有多少繪製調用被下達了,多少被經過批處理節省了。若是你圍繞着很小數量的紋理來組織你的幾何圖形,那麼確保不要實例化你的材質,並把靜態物體都標記上靜態的旗幟,這樣整個場景通常來講就比較節能環保綠色高效了。

透明,Alpha Test 以及重複繪製(Overdraw)

如上所說起,移動芯片通常都是「填充率瓶頸」,意味着像素填充多是一幀中佔用開銷最大的地方。減小填充開銷的關鍵就在於儘可能讓每個像素只被繪製一次。多通道着色器,逐像素光照效果(好比 Unity 的默認高光着色器)還有透明對象等都須要對像素進行屢次渲染。太多的話,就會影響總線。

做爲最佳實踐的標準之一,你能夠在質量設置(Quality Settings)中試着限制像素光照數(Pixel Light Count)爲一。若是超過了一,你也要確保本身知道是哪部分的問題以及其形成的開銷。一樣,儘可能讓透明的物體小。這裏的開銷由碰到的像素決定,所以你接觸到的像素越少,這幀渲染的速度就越快。當心那些透明的粒子效果,好比煙霧等,其涉及到的像素數量可能會超過你的預期。

此外還要注意你不該該在移動設備上去使用 alpha test 着色器,好比 Unity 的鏤空着色器(Cutout Shader)。那些 Alpha Test 的操做(以及 clip(),或者片斷着色器裏的顯式丟棄), 會強制目前多數移動 GPU 撤銷那些硬件優化,讓其運行變得極慢。在管線中丟棄片斷也常常會致使各類醜陋的反鋸齒,所以仍是請用不透明幾何或者 Alpha to coverage 來作鏤空。

性能節流

在你能可靠測試你的場景以前,你須要確保 CPU 和 GPU 的節流設置已經設定好了。由於 VR 遊戲已經把手機的性能壓榨到了極致,所以你須要好好掌握 CPU 和 GPU 之間的平衡。若是你的遊戲瓶頸在 CPU,那麼你能夠爲 GPU 降頻來讓 CPU 全速運轉。若是你的應用瓶頸在於 GPU 那你就反過來。若是你的應用效率很是高,那麼你能夠把 CPU 和 GPU 都降頻來下降耗電和溫度。能夠在 CPU 和 GPU 移動 SDK 文檔講述電源管理的章節「Power Management」 來查看更多關於 CPU 和 GPU 的節流設置方面的信息。

比較重要的一個地方是在作這類性能測試前必須先選定一個 CPU 和 GPU 的節流配置。若是這些具體的數值沒有被成功初始化,你的應用會被默認運行在降頻的環境下。因爲多數 Gear VR 的應用都會被 CPU 那邊的驅動開銷(好比繪製調用提交數目)所限制,所以通常來講對於頻率的設定會更有利 CPU 一些。你能夠在 OVRModeParams.cs 中找到一個關於如何初始化節流目標的例子,也能夠直接複製粘貼到一個在遊戲開始時執行的腳本里來檢驗效果。

注意事項

這幾天是你在考量本身應用性能表現時應當注意的:

  • 運行在 Lolipop 下驍龍805核心的 Note4 比起其它全部版本的 Note4 都要慢;貌似圖形驅動關於提交繪製調用這一塊有了退步。若是某些遊戲在繪製調用這一塊已經到底了那麼有可能會發現新的瓶頸(最多可能達增長20%的響應時間),足夠讓常規的管線停頓並致使幀率降低。咱們正努力和三星以及高通共通解決這個問題。運行安卓 4.4 的驍龍805 Note4 以及獵戶座 Note4 和 S6 設備皆不受此影響。
  • 儘管爲 CPU 和 GPU 進行降頻節流能極大下降手機的熱量,那些開銷大的應用在長時間的使用過程當中依然可能讓手機過熱。在這種狀況發生時,手機會發出警告,而後動態下降處理器的頻率,通常都會致使應用幀率低到不可用的地步。若是你在作性能測試時碰到了這種狀況,請關閉應用並讓手機休息個至少五分鐘再繼續測試。
  • Unity 4 免費版不支持靜態批處理以及 Unity Profiler。可是 Unity 5 我的版支持這些。
  • S6 不支持各向異性紋理過濾 。

目前基本就這麼多了。在下一貼,咱們將討論如何針對真實世界各類性能表現下降的問題來排錯。

如若需瞭解更多關於在 Unity 移動 VR 應用開發方面的優化問題,請在咱們的 Unity Integration guide裏查看「最佳實踐指南:移動端」這一節。

Via:Oculus 翻譯來源:VRerse元代碼

相關文章
相關標籤/搜索