12個優化Unity/GearVR應用的小技巧

比起那些普通應用,VR 應用所需的計算性能要求大了太多,讓優化成爲了一項重要工作。如果你的目標是類似 Gear VR 這種移動設備,那麼要求會更高。

以下爲一些基本的標杆:

  • 單眼 50 個繪製調用(Draw Call)。Unity5 更加精準地稱之爲 口令設置程序 調用(setpass calls)。
  • 少於50000-100000個頂點數以及50000-100000個多邊形數量。

確實是很嚴苛的要求,而這裏有一些小技巧來助你一臂之力。

靜態批處理(Static batching)

在一個場景裏,可能有一堆靜態幾何圖形,比如牆、椅子、燈光和各種靜止網格(Mesh)。你可以在編輯器裏把它們標成靜態。確保將他們標記成靜態光源映射來得到烘焙好的光照貼圖紋理。被標記成靜態的物品會被組成一個網格,而非每繪製一次物品就產生調用。

但靜態批處理有一個關鍵的要求:所有物品必須都有同樣的材質。如果你有木頭材質的靜態牆壁和一個鋼鐵材質的靜態椅子,所有牆壁會被組合成一個網格,消耗一個繪製調用,而椅子則也會有一個網格,佔用另一個繪製調用。

紋理集合(Texture atlasing)

如上文所提及,每個不同材質都會至少導致一個新的繪製調用。你可能會以爲一個木頭門和鐵椅子必須使用不同的材質,畢竟它們使用了不同的紋理。但是,如果它們 能使用同樣的着色器,你可以使用紋理集合來創建一個材質,同時兼容這兩個物體。一個紋理集合其實就是一個大紋理貼圖,裏面包含了各種各樣的小紋理。你可以讓某個材質加載幾個紋理而非讓一堆材質加載一堆紋理。每個物體都能通過不同的紋理映射來加載這個紋理集合上不同座標位置的一小片紋理。

你可以手動去做這個事,而作爲參考, Juan Sebastian’s Pro Draw Call Optimizer 非常有用。它能自動生成紋理集合,而不會干擾你的 assets。

動態批處理(Dynamic batching)

移動的非靜態物品也能被動態批處理爲單一繪製調用。這對於 CPU 來說開銷較大,每幀都經過計算,但就優化最終結果來說還是不錯的。不過要注意的是這隻對低於 900 個頂點並有着同樣材質的物體纔有用。使用紋理集合來爲你的動態物體創建一個單一材質,然後你就能得到簡單的動態批處理了。

多細節層次(Level Of Details)

多細節層次組也是一個提升表現的簡單方式。使用擁有多個細節層次的 assets 並讓離鏡頭遠的物體採取低細節的幾何圖形進行渲染。Unity 能自動在攝像頭和物體之間的距離發生改變時過渡到不同的細節層次。

填充率,重複繪製,過濾剔除(Fillrate, overdraw, and culling)

降低重複繪製,不要讓遠處物體的像素被繪製了後,近處覆蓋在這個像素的物體上面時又繪製了一次。對於平時在 PC 上倒不是太所謂,但對於移動 VR,這也是性能開銷啊。大量的重複繪製和高分辨率影響了你的填充率,而紋理填充率也是 GPU 的限制之一。

目前,解決方式包括遮擋剔除(occlusion culling)和層次視錐剔除(frustum culling)。層次視錐剔除能將攝像機視野錐體外的東西都剔除掉,畢竟渲染那些你根本沒有看着的東西毫無意義。而遮擋剔除則是不渲染那些被擋住的物體,比如門後的房間,沙發後的桌子什麼的。默認狀態下遮擋剔除能搞定你的整個當前場景,但如果關卡設計得當,整個關卡都能被剔除掉。

多細節層次組也能剔除掉離攝像頭太遠的物體,以進一步降低填充率。

關卡設計(Level design)

如果你的遊戲是讓玩家從一個房間(地區)到另一個房間(地區),那基本的方式就是讓整個遊戲只在一個關卡中。但這樣會導致過高的內存開銷 – 每一個房間內的物體和材質都會被加載到內存裏,即便在當前場景中是不可見的。所以,將房間放到不同的關卡里,通過代碼設計來分開加載。

異步加載(Asynchronous loading)

當玩家快要接近到加載下一關的門時,加載下一關。不要同時使用 Application.LoadLevel(),這會導致遊戲暫停卡頓。即便頭部跟蹤只停了一小會,也會讓玩家非常不適。

因此,採取 Application.LoadLevelAsync()。關於範例你可以查看 Oculus Mobile SDK 下的 BlockSplosion 樣品,在 StartupSample.cs 裏。

光照烘焙(Baked lighting)

關閉實時陰影!得到實時陰影的物體將無法被批處理,導致大量的額外繪製調用的開銷。

在 PC 上,你能僅通過單一的即時方向光來得到不錯的動態陰影,但在移動端,請用烘焙好的光照,不要用實時陰影。

陰影(Shadows)

尤其對於移動體驗來說,請對立體物品的陰影使用以前那些小技巧。半真實的陰影可以通過在物體下面增加一個平面模糊灰色圖形來達到。

比如,千萬不要用這種高端電腦才能搞定的 GTA V 實時動態陰影。

但你可以用類似這種:下圖來自2002年的 GTA 罪惡城市,只是在人物下面增加了一個模糊的小圓球而已。

光照探針(Light probes)

當使用烘焙好的光線後,那些動態物品看起來違和感很高,而靜態物品非常好。解決的辦法之一就是通過光照探針來模擬動態光源。

光照探針是烘焙好的立方體貼圖,在場景中的各個點上存儲直接、間接乃至發散的光線。當動態物體移動時,它會提取最近的幾個光照探針的樣品來模擬在那個部位的光線。這是模擬真實光線而無需依賴昂貴的實時光線的方式。

Unity 提供了一個 不錯的文檔 來告訴你應該如何放置光照探針。

避免透明和多材質物品

使用透明着色器的物品,比如玻璃,窗戶等都非常昂貴。還有一些專門讓物品看起來更真實的方式,比如在牆壁前增加一層鏽色或灰塵透明的材質等等。這類多材質 alpha 融合都非常昂貴,每個材質都會增加一個繪製調用。但是,多紋理就無所謂了,所以你應該只用一個材質,並用一個可以通過 alpha 融合來融合多個紋理的着色器。

蒙皮網格渲染器(Skinned mesh renderers)

蒙皮網格渲染器在渲染那些有動畫部件的角色時比較常用,能通過物理或定製的動畫來達到真實的網格變形。

不幸的是, 蒙皮網格渲染器不會被整合進批處理中去。每個場景裏的角色都會導致單眼增加幾個繪製調用。

Via: DSharkAR

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章