比起那些普通的應用,VR應用所需的計算性能要求要比非VR的大很多,所以它讓優化成為了一項重要工作;但如果你的目標是類似Gear VR這種移動設備,那麼要求會更高。
以下是一些基本的標杆:
單眼50個繪製調用(Draw Call),Unity5更加精準地稱之為口令設置程序調用(Setpass Calls)。
少於50000-100000個頂點數以及50000-100000個多邊形數量。
下麵是一些簡單的技巧,用於滿足上述要求:
1、靜態批處理(Static Batching)
在一個場景裏,可能有一堆靜態幾何圖形,比如牆、椅子、燈光和各種靜止網格(Mesh),你可以在編輯器裏把它們標成靜態,確保將他們標記成靜態光源映射來得到烘焙好的光照貼圖紋理。被標記成靜態的物品會被組成一個網格,而非每繪製一次物品就產生調用。
但靜態批處理有一個關鍵的要求:所有物品必須都有同樣的材質。如果你有木頭材質的靜態牆壁和一個鋼鐵材質的靜態椅子,所有牆壁會被組合成一個網格,消耗一個繪製調用,而椅子則也會有一個網格,占用另一個繪製調用。
2、紋理集合(Texture Atlasing)
如上文所提及,每個不同材質都會至少導致一個新的繪製調用,你可能會以為一個木頭門和鐵椅子必須使用不同的材質,畢竟它們使用了不同的紋理。但是如果它們能使用同樣的著色器,你可以使用紋理集合來創建一個材質,同時兼容這兩個物體。一個紋理集合其實就是一個大紋理貼圖,裏麵包含了各種各樣的小紋理。你可以讓某個材質加載幾個紋理而非讓一堆材質加載一堆紋理,每個物體都能通過不同的紋理映射來加載這個紋理集合上的不同坐標位置的一小片紋理。你也可以在繪製管線中手動生成紋理集,Juan Sebastian的Pro Draw Call Optimizer工具非常有用,它可以生成紋理集,並且在替換新對象時不會搞混資源。
3、動態批處理(Dynamic Batching)
移動非靜態物品也能被動態批處理為單一繪製調用,這對於CPU來說開銷較大,每幀都經過計算,但就優化最終結果來說還是不錯的。不過要注意的是這隻對低於900個頂點並有著同樣材質的物體才有用,使用紋理集合來為你的動態物體創建一個單一材質,然後你就能得到簡單的動態批處理了。
4、多細節層次(Level Of Details)
多細節層次組也是一個提升表現的簡單方式。使用多個細節層次的Assets並讓離鏡頭遠的物體采取低細節的幾何圖形進行渲染,Unity能自動在攝像頭和物體之間的距離發生改變時過渡到不同的細節層次。
5、填充率,重複繪製,過濾剔除(Fillrate,Overdraw and Culling)
降低重複繪製,不要讓遠處物體的像素被繪製了後,近處覆蓋在這個像素的物體上麵時又繪製了一次。對於平時在PC上倒不是無所謂,但對於移動VR,這也是性能開銷啊。大量的重複繪製和高分辨率影響了你的填充率,而紋理填充率也是GPU的限製之一。
目前,解決方式包括遮擋剔除(Occlusion Culling)和層次視錐剔除(Frustum Culling)。層次視錐剔除能將攝像機視野錐體外的東西都剔除掉;而遮擋剔除則是不渲染那些被擋住的物體,比如門後的房間,沙發後的桌子什麼的。默認狀態下遮擋剔除能搞定你的整個當前場景,但如果關卡設計得當,整個關卡都能被剔除掉,多細節層次組也能剔除掉離攝像頭太遠的物體,以進一步降低填充率。
6、關卡設計(Level Design)
如果你的遊戲是讓玩家從一個房間(地區)到另一個房間(地區),那基本的方式就是讓整個遊戲隻在一個關卡中,但這樣會導致過高的內存開銷,每一個房間內的物體和材質都會被加載到內存裏,即便在當前場景中是不可見的。所以,要將房間放到不同的關卡裏,通過代碼設計來分開加載。
7、異步加載(Asynchronous Loading)
當玩家快要接近到加載下一關的關門時,不要同時使用Application.LoadLevel(),這會導致遊戲暫停卡頓,即便頭部跟蹤隻停了一小會兒,也會讓玩家非常的不適。因此,要采取Application.LoadLevelAsync(),關於範例你可以查看Oculus Mobile SDK下的BlockSplosion樣品,在StartupSample.cs裏。
8、光照烘焙(Baked Lighting)
關閉實時陰影,得到實時陰影的物體將無法被批處理,導致大量的額外繪製調用的開銷。在PC上,你僅能通過單一的即時方向光來得到不錯的動態陰影,但在移動端請用烘焙好的光照,不要用實時陰影。
9、陰影(Shadows)
尤其對於移動體驗來說,請對立體物品的陰影使用以前的那些小技巧,半真實的陰影可以通過在物體下麵增加一個平麵模糊灰色圖形來達到。比如,千萬不要以為用這種高端電腦才能搞定GTA V的實時動態陰影。
但你也可以用類似這種:下圖來自2002年的GTA罪惡城市,隻是在人物下麵增加了一個模糊的小圓球而已。
10、光照探針(Light probes)
當使用烘焙好的光線後,那些動態物品看起來違和感很高,而靜態物品就非常好。解決的辦法之一就是通過光照探針來模擬動態光源。光照探針是烘焙好的立方體貼圖,在場景中的各個點上存儲直接、間接乃至發散的光線。當動態物體移動時,它會提取最近的幾個光照探針的樣品來模擬在那個部位的光線,這是模擬真實光線而無需依賴昂貴的實時光線的方式。
11、避免透明和多材質物品
使用透明著色器的物品,比如玻璃,窗戶等都非常昂貴。還有一些專門讓物品看起來更真實的方式,比如在牆壁前增加一層鏽色或灰塵透明的材質等等,這類多材質Alpha融合都非常昂貴,每個材質都會增加一個繪製調用。但是,多紋理就無所謂了,所以你應該隻用一個材質,並用一個可以通過Alpha來融合多個紋理的著色器。
12、蒙皮網格渲染器(Skinned mesh renderers)
蒙皮網格渲染器在渲染那些有動畫部件的角色時比較常用,能通過物理或定製的動畫來達到真實的網格變形。不幸的是,蒙皮網格渲染器不會被整合進批處理中去,每個場景裏的角色都會導致單眼增加幾個繪製調用。