Unity3d代碼及效率優化總結

最簡單的優化建議:

1.PC平臺的話保持場景中顯示的頂點數少于200K~3M,移動設備的話少于10W,一切取決于你的目標GPU與CPU。

2.如果你用U3D自帶的SHADER,在表現不差的情況下選擇Mobile或Unlit目錄下的。它們更高效。

3.盡可能共用材質。

4.將不需要移動的物體設為Static,讓引擎可以進行其批處理。

5.盡可能不用燈光。

6.動態燈光更加不要了。

7.嘗試用壓縮貼圖格式,或用16位代替32位。

8.如果不需要別用霧效(fog)

9.嘗試用OcclusionCulling,在房間過道多遮擋物體多的場景非常有用。若不當反而會增加負擔。

10.用天空盒去“褪去”遠處的物體。

11.shader中用貼圖混合的方式去代替多重通道計算。

12.shader中注意float/half/fixed的使用。

13.shader中不要用復雜的計算pow,sin,cos,tan,log等。

14.shader中越少Fragment越好。

15.注意是否有多余的動畫腳本,模型自動導入到U3D會有動畫腳本,大量的話會嚴重影響消耗CPU計算。

16.注意碰撞體的碰撞層,不必要的碰撞檢測請舍去。

1.為什么需要針對CPU(中央處理器)與GPU(圖形處理器)優化?

CPU和GPU都有各自的計算和傳輸瓶頸,不同的CPU或GPU他們的性能都不一樣,所以你的游戲需要為你目標用戶的CPU與GPU能力進行針對開發。

2.CPU與GPU的限制

GPU一般具有填充率(Fillrate)和內存帶寬(Memory Bandwidth)的限制,如果你的游戲在低質量表現的情況下會快很多,那么,你很可能需要限制你在GPU的填充率。

CPU一般被所需要渲染物體的個數限制,CPU給GPU發送渲染

物體命令叫做DrawCalls。一般來說DrawCalls數量是需要控制的,在能表現效果的前提下越少越好。通常來說,電腦平臺上DrawCalls

幾千個之內,移動平臺上DrawCalls幾百個之內。這樣就差不多了。當然以上并不是絕對的,僅作一個參考。

往往渲染(Rendering)并不是一個問題,無論是在GPU和CPU上。很可能是你的腳本代碼效率的問題,用Profiler查看下。

關于Profiler介紹:http://docs.unity3d.com/Documentation/Manual/Profiler.html

需要注意的是:

在GPU中顯示的RenderTexture.SetActive()占用率很高,是因為你同時打開了編輯窗口的原因,而不是U3D的BUG。

3.關于頂點數量和頂點計算

CPU和GPU對頂點的計算處理都很多。GPU中渲染的頂點數取決于GPU性能和SHADER的復雜程度,一般來說,每幀之內,在PC上幾百萬頂點內,在移動平臺上不超過10萬頂點。

CPU中的計算主要是在蒙皮骨骼計算,布料模擬,頂點動畫,粒子模擬等。GPU則在各種頂點變換、光照、貼圖混合等。

【個人認為,具體還是看各位的項目需求,假設你項目的是3d游戲。你游戲需要兼容低配置的硬件、流暢運行、控制硬件發熱的話,還要達到一定效果(LIGHTMAP+霧效),那么頂點數必定不能高。此時同屏2W頂點我認為是個比較合適的數目,DRAWCALL最好低于70。另,控制發熱請控制最高上限的幀率,流暢的話,幀率其實不需要太高的。】

4.針對CPU的優化——減少DRAW CALL 的數量

為了渲染物體到顯示器上,CPU需要做一些工作,如區分哪個東西需要渲染、區分開物體是否受光照影響、使用哪個SHADER并且為SHADER傳參、發送繪圖命令告訴顯示驅動,然后發送命令告訴顯卡刪除等這些。

假設你有一個上千三角面的模型卻用上千個三角型模型來代替,在GPU上花費是差不多的,但是在CPU上則是極其不一樣,消耗會大很多很多。為了讓CPU更少的工作,需要減少可見物的數目:

a.合并相近的模型,手動在模型編輯器中合并或者使用UNITY的Draw call批處理達到相同效果(Draw call batching)。具體方法和注意事項查看以下鏈接:

Draw call batching : http://docs.unity3d.com/Documentation/Manual/DrawCallBatching.html

b.在項目中使用更少的材質(material),將幾個分開的貼圖合成一個較大的圖集等方式處理。

如果你需要通過腳本來控制單個材質屬性,需要注意改變Renderer.material將會造成一份材質的拷貝。因此,你應該使用Renderer.sharedMaterial來保證材質的共享狀態。

有一個合并模型材質不錯的插件叫Mesh Baker,大家可以考慮試下。

c.盡量少用一些渲染步驟,例如reflections,shadows,per-pixel light 等。

d.Draw call batching的合并物體,會使每個物體(合并后的物體)至少有幾百個三角面。

假設合并的兩個物體(手動合并)但不共享材質,不會有性能表現上的提升。多材質的物體相當于兩個物體不用一個貼圖。所以,為了提升CPU的性能,你應該確保這些物體使用同樣的貼圖。

另外,用燈光將會取消(break)引擎的DRAW CALL BATCH,至于為什么,查看以下:

Forward Rendering Path Details:

http://docs.unity3d.com/Documentation/Components/RenderTech-ForwardRendering.html

e.使用相關剔除數量直接減少Draw Call數量,下文有相關提及。

5.優化幾何模型

最基本的兩個優化準則:

a.不要有不必要的三角面。

b.UV貼圖中的接縫和硬邊越少越好。

需要注意的是,圖形硬件需要處理頂點數并跟硬件報告說的并不一

樣。不是硬件說能渲染幾個點就是幾個點。模型處理應用通展示的是幾何頂點數量。例如,一個由一些不同頂點構成的模型。在顯卡中,一些集合頂點將會被分離

(split)成兩個或者更多邏輯頂點用作渲染。如果有法線、UV坐標、頂點色的話,這個頂點必須會被分離。所以在游戲中處理的實際數量顯然要多很多。

6.關于光照

若不用光肯定是最快的。移動端優化可以采用用光照貼圖(Lightmapping)去烘培一個靜態的貼圖,以代替每次的光照計算,在U3D中只需要非常短的時間則能生成。這個方法能大大提高效率,而且有著更好的表現效果(平滑過渡處理,還有附加陰影等)。

在移動設備上和低端電腦上盡量不要在場景中用真光,用光照貼圖。這個方法大大節省了CPU和GPU的計算,CPU得到了更少的DRAWCALL,GPU則需要更少頂點處理和像素柵格化。

Lightmapping : http://docs.unity3d.com/Documentation/Manual/Lightmapping.html

7.對GPU的優化——圖片壓縮和多重紋理格式

Compressed Textures(圖片壓縮):

http://docs.unity3d.com/Documentation/Components/class-Texture2D.html

圖片壓縮將降低你的圖片大小(更快地加載更小的內存跨度(footprint)),而且大大提高渲染表現。壓縮貼圖比起未壓縮的32位RGBA貼圖占用內存帶寬少得多。

之前U3D會議還聽說過一個優化,貼圖盡量都用一個大小的格式(512 * 512 , 1024 * 1024),這樣在內存之中能得到更好的排序,而不會有內存之間空隙。這個是否真假沒得到過測試。

MIPMAps(多重紋理格式):

http://docs.unity3d.com/Documentation/Components/class-Texture2D.html

跟網頁上的略縮圖原理一樣,在3D游戲中我們為游戲的貼圖生成多重紋理貼圖,遠處顯示較小的物體用小的貼圖,顯示比較大的物體用精細的貼圖。這樣能更加有效的減少傳輸給GPU中的數據。

8.LOD 、 Per-Layer Cull Distances 、 Occlusion Culling

LOD (Level Of Detail) 是很常用的3D游戲技術了,其功能理解起來則是相當于多重紋理貼圖。在以在屏幕中顯示模型大小的比例來判斷使用高或低層次的模型來減少對GPU的傳輸數據,和減少GPU所需要的頂點計算。

攝像機分層距離剔除(Per-Layer Cull Distances):為小物體標識層次,然后根據其距離主攝像機的距離判斷是否需要顯示。

遮擋剔除(Occlusion Culling)其實就是當某個物體在攝像機前被另外一個物體完全擋住的情況,擋住就不發送給GPU渲染,從而直接降低DRAW CALL。不過有些時候在CPU中計算其是否被擋住則會很耗計算,反而得不償失。

以下是這幾個優化技術的相關使用和介紹:

Level Of Detail :

http://docs.unity3d.com/Documentation/Manual/LevelOfDetail.html

Per-Layer Cull Distances :

http://docs.unity3d.com/Documentation/ScriptReference/Camera-layerCullDistances.html

Occlusion Culling :

http://docs.unity3d.com/Documentation/Manual/OcclusionCulling.html

9.關于Realtime Shadows(實時陰影)

實時陰影技術非常棒,但消耗大量計算。為GPU和CPU都帶來了昂貴的負擔,細節的話參考下面:

http://docs.unity3d.com/Documentation/Manual/Shadows.html

10.對GPU優化:采用高效的shader

a.需要注意的是有些(built-in)Shader是有mobile版本的,這些大大提高了頂點處理的性能。當然也會有一些限制。

b.自己寫的shader請注意復雜操作符計算,類似pow,exp,log,cos,sin,tan等都是很耗時的計算,最多只用一次在每個像素點的計算。不推薦你自己寫normalize,dot,inversesqart操作符,內置的肯定比你寫的好。

c.需要警醒的是alpha test,這個非常耗時。

d.浮點類型運算:精度越低的浮點計算越快。

在CG/HLSL中--

float :32位浮點格式,適合頂點變換運算,但比較慢。

half:16位浮點格式,適合貼圖和UV坐標計算,是highp類型計算的兩倍。

fixed: 10位浮點格式,適合顏色,光照,和其他。是highp格式計算的四倍。

寫Shader優化的小提示:

http://docs.unity3d.com/Documentation/Components/SL-ShaderPerformance.html

11.另外的相關優化:

a.對Draw Call Batching的優化

http://docs.unity3d.com/Documentation/Manual/DrawCallBatching.html

b.對Rendering Statistics Window的說明和提示:

http://docs.unity3d.com/Documentation/Manual/RenderingStatistics.html

c.角色模型的優化建議

用單個蒙皮渲染、盡量少用材質、少用骨骼節點、移動設備上角色多邊形保持在300~1500內(當然還要看具體的需求)、PC平臺上1500~4000內(當然還要看具體的需求)。



Unity3D代碼及效率優化總結

1、在使用數組或ArrayList對象時應當注意

length=myArray.Length;

for(inti=0;i

{

}

避免

for(inti=0;i

{

}

2、如果沒有必要每幀都處理,則可以每隔幾幀處理一次

voidUpdate(){if(Time.frameCount%6==0)?{?DoSomething();?}}

3、定時重復調用可以使用InvokeRepeating函數實現,比如,啟動0.5秒后每隔1秒執行一次 DoSomeThing 函數:

voidStart()

{

InvokeRepeating("DoSomeThing",?0.5f,?1.0f);

}

4、少使用臨時變量,特別是在Update OnGUI等實時調用的函數中。

voidUpdate()

{

Vector3?pos;

pos=transform.position;

}

可以改為:

privateVector3?pos;

voidUpdate()

{

pos=transform.position;

}

5、主動進行垃圾回收

voidUpdate()

{

if(Time.frameCount%50==0)

{

System.GC.Collection();

}

}

6、優化數學運算,盡量避免使用float,而使用int,特別是在手機游戲中,盡量少用復雜的數學函數,比如sin,cos等函數。改除法/為乘法,例如:使用x*0.5f而不是 x/2.0f 。

7、壓縮?Mesh

導入?3D?模型之后,在不影響顯示效果的前提下,最好打開?Mesh?Compression。??Off,?Low,?Medium,?High?這幾個選項,可酌情選取。對于單個Mesh最好使用一個材質。

8、?運行時盡量減少?Tris?和?Draw?Calls

預覽的時候,可點開?Stats,查看圖形渲染的開銷情況。特別注意?Tris?和?Draw?Calls?這兩個參數。??一般來說,要做到:??Tris?保持在?7.5k?以下??,Draw?Calls?保持在?35?以下。

9、避免大量使用?Unity?自帶的?Sphere?等內建?Mesh

Unity?內建的?Mesh,多邊形的數量比較大,如果物體不要求特別圓滑,可導入其他的簡單3D模型代替。

10、

如果可能,將GameObject上不必要的腳本disable掉。如果你有一個大的場景在你的游戲中,并且敵方的位置在數千米意外,這是你可以

disable你的敵方AI腳本直到它們接近攝像機為止。一個好的途徑來開啟或關閉GameObject是使用

SetActiveRecursively(false),并且球形或盒型碰撞器設為trigger。

11、刪除空的Update方法。當通過Assets目錄創建新的腳本時,腳本里會包括一個Update方法,當你不使用時刪除它。

12、引用一個游戲對象的最合乎邏輯的組件。有人可能會這樣寫someGameObject.transform,gameObject.rigidbody.transform.gameObject.rigidbody.transform,但是這樣做了一些不必要的工作,你可以在最開始的地方引用它,像這樣:

privateTransform myTrans;

void Start()

{

myTrans=transform;

}

13、協同是一個好方法。可以使用協同程序來代替不必每幀都執行的方法。(還有InvokeRepeating方法也是一個好的取代Update的方法)。

14、盡可能不要再Update或FixedUpdate中使用搜索方法(例如GameObject.Find()),你可以像前面那樣在Start方法里獲得它。

15、不要使用SendMessage之類的方法,他比直接調用方法慢了100倍,你可以直接調用或通過C#的委托來實現。

16、使用javascript或Boo語言時,你最好確定變量的類型,不要使用動態類型,這樣會降低效率,你可以在腳本開頭使用#pragmastrict 來檢查,這樣當你編譯你的游戲時就不會出現莫名其妙的錯誤了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,441評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,211評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,475評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,834評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,009評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,559評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,306評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,516評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,728評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,249評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,484評論 2 379

推薦閱讀更多精彩內容