vr优化
轉(zhuǎn)載自博主狂云歌 原文章鏈接http://blog.csdn.net/madcloudsong/article/details/52446813
【狂云歌之unity_vr】VR開發(fā)中的優(yōu)化
前言
大概做了大半年的VR開發(fā),HTCVive上與room scale和手柄控制器、激光相關(guān)的開發(fā)做過,gearvr使用oculus sdk開發(fā)做過,使用Cardboard做普通VR app在Android和iOS上發(fā)布也做過。
vr設(shè)備呢,HTCVive和oculus搞過,gearvr和普通Cardboard類的手機(jī)vr搞過,LG的新的glass接過,露光嚴(yán)重,idealens、還有一大票的國產(chǎn)一體機(jī),pico、小米,嗯做的好的目前的確還是那幾個大廠的。
由于我參與的項目主要圍繞視頻播放的功能,所以大型3d場景接觸的倒不多,然而還是有很多需要優(yōu)化的點(diǎn),為什么呢,因為做的視頻播放本身就需要對大于1080p的視頻做解碼、在unity中渲染,對cpu和gpu消耗都很大,擠占了部分性能,所以對其他邏輯和渲染部分的性能要求更高。
VR開發(fā)中的優(yōu)化主要圍繞兩部分吧,一部分是由于VR的特殊場景,雙眼渲染,且對幀率要求高,所以對性能要求也高,還有vr場景下一些特殊要求。另一部分是傳統(tǒng)unity性能優(yōu)化部分,對程序和美術(shù)都有要求。unity相關(guān)的優(yōu)化網(wǎng)上已經(jīng)有很多優(yōu)秀的文章了,我在這只根據(jù)VR開發(fā)與傳統(tǒng)unity開發(fā)的區(qū)別,分享一些優(yōu)化的建議。
歡迎下載我們的app
VR優(yōu)化
先從VR幀率卡說起
因為HTCVive和gearvr做的開發(fā)比較多,先說說這兩個設(shè)備卡的表現(xiàn),對于HTCVive而言,如果程序執(zhí)行時卡頓比如loading或者什么,一般會優(yōu)雅的回到HTCVive的一個默認(rèn)場景,對用戶還算比較友好,而對于gearvr而言,如果卡頓影響了渲染或者幀率低,那么用戶頭轉(zhuǎn)動的時候能明顯看到周圍來不及渲染的黑的地方,如果渲染卡死的話,只剩最后一幀渲染的畫面,周圍的空間都是黑的。
對于PC而言,我們配置的顯卡至少也會是970+吧,性能都比較好,cpu、渲染、IO等性能都比較高,但是到了移動端,相應(yīng)操作性能都會變差,之前對比過一些操作,比如圖片動態(tài)加載,在editor下可能只要幾毫秒最多20幾毫秒,到了移動端可能都要幾十毫秒甚至2-500毫秒的都有,那么幀率降低的簡直不要不要的。所以對于unity而言,不光在editor下看性能指標(biāo),也要利用profiler觀察在移動設(shè)備的性能。我們在開發(fā)過程中和測試中都要不斷的進(jìn)行性能優(yōu)化。
VR和傳統(tǒng)游戲卡的區(qū)別
傳統(tǒng)游戲也會做很多的性能優(yōu)化,但是卻可以有很多常用的解決方案,例如為了解決資源包大的問題,將資源通過異步下載并動態(tài)加載,為了減少加載的損耗,那么大不了加一個loading畫面,而loading時一般而言隨便卡,不太需要關(guān)注操作的阻塞延遲和幀率,因為loading時無需響應(yīng)用戶操作。甚至有的游戲按一個按鈕也會進(jìn)行阻塞,大不了出個loading嘛反正用戶也會等。
對于VR應(yīng)用,用戶都是可以自由操作轉(zhuǎn)頭的,一旦卡頓,影響幀率,直接會影響用戶視野轉(zhuǎn)動,影響體驗,同時降低幀率刷新后,用戶會有眩暈感,那么就很失敗。
一般什么時候會發(fā)生卡頓呢,對于vr程序開發(fā)而言,往往出現(xiàn)在場景切換時資源加載、初始化腳本邏輯執(zhí)行,例如monobehaviour的awake和start里包含的大量的邏輯,甚至你以為使用了協(xié)程就沒有問題,然而協(xié)程在首次執(zhí)行時第一個yield前可能也包含了大量的邏輯。還有運(yùn)行時動態(tài)資源加載以及常見的每幀處理事情過多導(dǎo)致降幀。
性能優(yōu)化工具
unity提供了一些性能指標(biāo)查看工具,比如profiler和frame debug。
profiler
profiler可以看cpu、render、內(nèi)存等性能消耗,一般可以看出每一幀哪些操作分別消耗了多少時間,找到瓶頸進(jìn)行優(yōu)化。例如我之前在pc上看性能貌似都還可以,但是在gearvr移動端就明顯的看到像Resource.Load()這種操作過多的占用了時間于是優(yōu)化掉。
另外注意不必要的log記得清理,否則在profiler里會占用很多時間。
profiler也可以實時查看unity程序在Android和iOS上運(yùn)行時的性能表現(xiàn)。
framedebug
framedebug可以方便的查看一幀都進(jìn)行了哪些渲染,可以用來優(yōu)化drawcall,在做vr開發(fā)的時候,因為雙眼渲染,所以drawcall比普通程序也會高很多,正常表現(xiàn)是2倍的drawcall,具體平臺就算進(jìn)行了一定的優(yōu)化,看起來往往也要多50%以上的drawcall。
嗯具體優(yōu)化drawcall的方式常規(guī)游戲中也有蠻多,我只說我們做的簡單且立竿見影的優(yōu)化,因為ugui用的多,那么用ugui的sprite pack之后drawcall可以直接ugui中大量sprite的drawcall,再加上雙倍的渲染,drawcall的節(jié)約其實非常可觀,而不用做太多事情。
一些優(yōu)化的經(jīng)驗
場景異步加載
在切換場景的時候,使用異步接口進(jìn)行l(wèi)oad,還是之前說的,同步load會導(dǎo)致卡頓而影響渲染。通過異步加載場景,盡量減少阻塞的時間,因為場景加載完畢運(yùn)行的時候,初始化相關(guān)例如awake和start還是會導(dǎo)致一定的卡頓,這個就要通過后面的方式來解決。
資源分散到每一幀加載
例如加載一些prefab等資源,很多想load就load,或者集中在某個函數(shù)里依次load好,但是這樣其實還是會導(dǎo)致卡頓。所以可以考慮使用協(xié)程等將資源加載分散到每一幀進(jìn)行加載,這樣也可以很快的在幾幀內(nèi)加載完畢,同時幀率也幾乎不會下降。
腳本分散到每一幀執(zhí)行
做項目的時候,在通過profiler調(diào)查性能時,有發(fā)現(xiàn)某一幀干了很多事情,導(dǎo)致卡頓。例如通過for循環(huán)干什么事情再用協(xié)程加載10張圖片,那么這些操作雖然單獨(dú)一個操作只要2-3ms不影響幀率,但是多個累計起來可能就高達(dá)幾十ms甚至更高,就會影響幀率。
另外如果開了10個協(xié)程加載10張圖片,很有可能在圖片下載ok之后,在同一幀之內(nèi)多張圖片同時轉(zhuǎn)為texture,這個操作很耗時,于是會累計導(dǎo)致卡頓,所以我也封裝了一個用來控制類似操作的協(xié)程,每一幀只會執(zhí)行一次這種阻塞耗時操作。
(必殺)黑屏
如果實在沒辦法,那就在特殊阻塞操作之前給用戶一個預(yù)期吧,同時漸變黑屏掉,這樣全黑的情況下,就算渲染卡頓了,用戶也看不出來。比如切換場景后開始的時候會比較卡,可能高達(dá)幾百ms甚至1秒,那么我就給用戶預(yù)期是loading切換場景,先切到黑屏再阻塞,然后渲染ok了再恢復(fù)渲染。我看了有的app也是這樣做的。
一個圖片處理優(yōu)化的例子
對于vr視頻播放app而言,顯示各種網(wǎng)絡(luò)上的圖片是一個比較常見的事情,在vr場景下,圖片分辨率不能太低,而恰巧我們服務(wù)器提供了一張分辨率較低的縮略圖和分辨率較高的大圖,使用小圖呢,不夠清晰,使用大圖呢,過于清晰,會造成閃的效果,同時loading大圖比較慢,不劃算,所以希望得到一個適當(dāng)尺寸的圖。讓服務(wù)器去多給張合適的圖,是最快最方便的途徑,然而~好吧還是希望在客戶端處理一下。
unity實現(xiàn)
如果使用unity的texture相關(guān)函數(shù),由于unity動態(tài)生成大texture比較慢,在pc上都要幾十ms,如果到了移動端差不多要幾百ms,而且是同步阻塞操作,這個完全不能接受。
如果使用unity多線程操作呢,然而unity多線程不能處理渲染相關(guān)的類例如texture。
或者使用基本c#實現(xiàn),一般的處理方法是使用System.Drawing,但是也不跨平臺,理論上應(yīng)該有直接對圖片數(shù)據(jù)處理的辦法,但是當(dāng)時也沒有那么多精力去研究。
native實現(xiàn)
使用unity下載圖片并緩存到本地,寫個android的Java插件,使用android多線程處理圖片,然后回調(diào)unity(此處也可封裝為協(xié)程),這樣對unity而言就只剩下JNI的調(diào)用開銷和load適當(dāng)大小圖片的開銷了。當(dāng)然對于iOS平臺需要再寫一個小插件。
Unity優(yōu)化
使用unity做vr開發(fā),那么優(yōu)化很多也是基于傳統(tǒng)unity游戲開發(fā)的優(yōu)化經(jīng)驗。由于unity接觸也不夠深入,所以基本也是參考其他人的優(yōu)化方法,逐漸去學(xué)習(xí)使用和深入了解。
舉例參考
http://www.cnblogs.com/murongxiaopifu/p/4284988.html
等等,這個unity優(yōu)化相關(guān)可以百度或者google到很多系統(tǒng)的文章,大同小異。優(yōu)化之路漫漫。
結(jié)語
總之傳統(tǒng)unity游戲開發(fā)有很多種途徑進(jìn)行優(yōu)化,必要時也可以有很多種方式避免用戶輸入和感知卡頓,可以在某些情況下降幀,而VR開發(fā)由于雙眼渲染、頭部控制的存在,對性能要求更高,壓榨幀率,需要降幀的時候也需要特殊處理(例如黑屏)。
我看HTCVive上有些app在配有980的相對配置較高的機(jī)器上也很卡頓,還是希望可以在細(xì)節(jié)處優(yōu)化,在用戶體驗上可以流暢。
總結(jié)
- 上一篇: 视频教程-清华-尹成老师-java基础-
- 下一篇: 微信二维码扫描支付