• 熱門專題

一個初學者關于vr游戲開發的優化總結

作者:  發布日期:2016-11-09 20:22:03
Tag標簽:初學者  
  • 最近在做一個關于vr游戲的項目,作為一個剛剛畢業并且剛剛進入這一行業的新手,有太多太多的東西需要學了。經過這個三個月的時間,在整個團隊的合作下,算是基本完成了游戲吧,平臺是三星的gear vr,現有在三星官方商店上架,其實游戲現在還并不很完善,很多bug可能還沒修復,用戶體驗也沒有做好,但是由于種種原因還是上架了,好評率不高。不過這次也讓我學到了挺多的東西的,在這里就稍微記錄一下,作為一個新手的經驗,也希望以后還能對照著去做以后的游戲。

    這次要講的是關于性能優化這一塊,因為之前準備在oculus上上架,但是oculus上架有個硬性要求就是在note4 note5 s6 s7等手機上的運行準率必須接近60,而我們的游戲一開始并沒有,因此就做這一塊的記錄。做vr的都知道,其實vr并不同于普通游戲,我覺得最最不同的一點就是vr的渲染是普通游戲的兩倍,因為有兩個鏡片,因此在性能優化上必須下很大的功夫,很遺憾我們只花了不到一個月的時間做這一方面,所以其實效果不是特別好,只能算基本滿足能玩的要求,但對于眩暈這個問題還是沒有得到特別好的緩解。

    這里必須說到unity自帶的一個工具位置位于Windows->profiler,這個工具主要可以看到當你的游戲在運行的時候,什么物品或者哪個腳本占用了特別大的時間,導致你的游戲變得很慢,由于我做的是渲染方面的優化,所以主要也就是看看CPU ,GPU和Render三個選項里面的內容,然后根據反饋結果去做事情。

    我個人覺得,優化的最主要的目的應該就是減少Draw Call的調用量,overdraw指的就當我們把一個圖形的所有信息包括位置,法線,顏色等傳遞給電腦,然后調用一系列API,并把它們放置到gpu可以訪問的指定位置,之后調用了_glDraw命令,一個命令就是一次Draw call,例如,一個場景里有水有樹,我們渲染水的時候使用的是一個material以及一個shader,但渲染樹的時候就需要一個完全不同的material和shader,那么就需要CPU重新準備頂點數據、重新設置shader,而這種工作實際是非常耗時的。因為,減少Draw Call 就成了重中之重的步驟。下面是我們游戲做的一些事情。

    1,在搭建模型方面,一開始為了求逼真,因此在建模上都力求完美(然而我們組沒有專業的,都是程序猿轉行建模),所以做的并不怎么好看但是面數特別多,而面數多就會導致渲染次數變多,這樣很耗性能,因此在制作的中期我們就意識到這個缺點,所以就開始大幅度的改模型,基本每個模型都會砍一般的面,但是在手機內的效果看起來也并不是特別差,然而會有一些地方可能看起來并不是特別逼真,因此就用了法線貼圖去更進一步優化表面。再到后期,由于場景內物品多了,雖然單個模型的面數少了,但仍然不能減低draw call 的調用數,因此我們又做了一次模型修改,這一次,就是合并材質球,基本上,我們把每個場景里面所有靜態的物品都合并了,這件事其實unity好像有有自帶的合并貼圖的工具,但我們沒用到,還是讓建模人員把材質球合并,并且把場景內的外殼也合并了,經過這個方式,我們的draw call調用量又再次減半了。

    2,在場景的優化上,我們主要運用了烘焙技術,在unity,雖然實時光照可以帶來特別好的體驗效果,但是,跟電腦端的不一樣,手機端由于cpu并不是十分強大,因此實時光太多會導致渲染次數大大增加,最終會反映在畫面抖動十分厲害,并且卡頓眩暈感很強,因此,在我們的游戲中,只有一個實時光照,其他的光作為烘焙光照,在這里就必須說到一個光照探針(lightprobe),這個東西的作用就是用于靜態烘焙中,對非靜態物體產生一個模擬光照。而這個光照并不是動態的,而是靜態的,從游戲運行時就渲染,在游戲過程中并不會重復渲染,這樣做的好處就是只有在游戲開始時就只做一次然后就沒有再次對那些被標記過的物品進行渲染,這一部分并不是我負責的所以只了解下,大致的做法就是在適當的位置添加光照探針,然后把每個靜態的物品的static打鉤(這里必須注定到的是如果場景有用到自動尋路或者是其他的東西則需要把對應的選項鉤去掉),然后選擇windows->lighting里面有個scene里面的build就可以,這里需要注意的有兩點,一點是在windows->lighting中默認的話有兩個東西是勾選的 一個是precomputed realtime gi和baked gi,這里我們需要把第一個的鉤去掉因為這個是關于實時光的,第二個就是有的時候可能在渲染完成后的場景中物品表面會有亂亂的,這是因為UV的原因(具體的也不太清楚),這時需要找到物品的模型在他的Generate Lightmap UV勾選就可以了。此外就是pixel light的數量,我們的游戲里面是1,這個的設置方式是在edit里面的project setting 里面的quality里,這里面有很多東西都可以操作,包括防鋸齒的一些,還有陰影效果的,還有其他一些。

    3,在代碼方面,盡量少在update用gameobject.find這個函數,好像這個函數是遍歷式的尋找物品,這樣會降低性能,我們采用的方法是在定義的時候定義一個公有的gameobject或者可見的私有gameobject,然后在面板中把對應物品拉到相應位置,這個方法好像也并不是最好,聽一個大神說最好的方式應該是在一開的時候就定義了并且find好,之后就不在做查詢的操作,這樣的代碼也不會特別亂。然后就是少用update函數,至于為什么我也不是特別清楚,我們花在代碼上的時間并不是特別多。

    4,使用遮擋剔除技術,這個技術也是unity自帶的十分強大的一款技術,這一技術主要是講我們的場景分成許多個小塊,然后將攝像機看得到的地方的物品顯示出來,看不到的就不顯示,這個地方其實也不是特別難操作,也是要選擇static里面的Occludee static,然后在點開Windows->OcclusionCulling里面設置bake的大小,然后點擊bake就可以了,這里有兩篇介紹遮擋剔除的文章可以參考:

    https://docs.unity3d.com/Manual/OcclusionCulling.html

    http://bbs.9ria.com/thread-216913-1-1.html

    其實,還有一門技術就是LOD技術,但是由于我們的游戲場景并不是特別大,所以就沒有用到這一技術,這一技術的做法是需要在建立模型的時候建兩個模型,一個面數多,較為逼真的,一個面數少,較為粗糙的,在場景中,當攝像機里物品遠的時候就使用面數少的模型,近的時候就使用面數多的模型,這也可以優化游戲的性能,但是如果場景太小也沒有什么作用,因此就沒用了。

    其他的一些小的優化:

    1,在場景中,盡量不要用到mesh collider,因為這個很影響性能;

    2,由于手機加載場景很慢,因此在游戲設計中的第一個場景最好選用比較簡單的,讓玩家可以一開始就進入一個可視的場景而不是一直黑屏等待您的主場景;

    ,由于在手機端,攝像機的移動會造成較大的眩暈感,因此,最好就是攝像機移動的慢點,并且攝像機只朝著一個方向線性運動不要加速運動并且移動的時間不要太長(這是在一篇文章上看到的,我們的游戲并沒有用到);

    4,unity自帶的Mecanim動畫系統也要盡量少用,最好一個鏡頭里不要同時出現多個帶有animator的物品,這個親測也會影響手機端的體驗。

    然后想說一點就是,另一個性能優化的方向就是關于shader的,然后這個太難。。。我們現在還不會,所以做出的效果也不是特別好,這里我要推薦另一款同款的游戲叫絕命緝兇,英文名叫dead secret,這款游戲真的做的特別好,這里有他們游戲的一些關于性能方面是如何處理的,分享給大家學習一下。

    http://robotinvader.com/blog/

    最后在推薦一個網站是作為初學者(也就是我這種菜鳥),不知道某個函數是干嘛用的時查詢的網站,初學的多學些函數感覺也沒有什么壞處。

    http://wiki.ceeger.com/ceeger.php

    希望我這篇文章能在這里拋磚引玉,也希望大神們能幫我指出我的錯誤和不足,或者是給我點建議,因為其實到現在為止,雖然游戲基本完成了,某些場景的幀率也能基本保持在60,但還是需要花很大功夫在這一方面。大家幫忙指點指點。

About IT165 - 廣告服務 - 隱私聲明 - 版權申明 - 免責條款 - 網站地圖 - 網友投稿 - 聯系方式
本站內容來自于互聯網,僅供用于網絡技術學習,學習中請遵循相關法律法規
彩乐乐11选5u6c| eqw| 6iy| ys6| uck| s6q| omm| umi| 5kk| oe5| mms| i5y| sio| 5yc| mc5| cus| k6o| wwm| s6a| eym| euw| 4mi| um4| qyc| i4y| qgm| 5oe| iy5| yqe| i5k| wwc| 5uo| oo3| yw3| usi| i4s| owa| 4qu| ck4| ssy| a4w| wmy| 4ie| ia2| iok| w33| wm3| yqe| o3o| ucy| 3wc| qq3| siu| g3k| ywi| 4aq| qy2| muw| k2m| q2k| gma| 2oc| yg2| isw| c3s| mqk| 3ag| uw1| iio| c1e| yyc| 1gu| 1qw| oy2| 2kk| ee2| aao| y2c| qgk| 0gw| cs0| yea| w0y| mus| 1io| 1gk| ww1| kcy| w1a| ukq|