【轉】unity3d 各類優化綜合

 

 


  檢測方式:

  一,unity3d 渲染統計窗口

  Game視窗的Stats去查看渲染統計的信息:

  一、FPS

  fps其實就是 frames per second,也就是每一秒遊戲執行的幀數,這個數值越小,說明遊戲越卡。

  二、Draw calls

  batching以後渲染mesh的數量,和當前渲染到的網格的材質球數量有關。

  三、Saved by batching

  渲染的批處理數量,這是引擎將多個對象的繪製進行合併從而減小GPU的開銷;

  不少GUI插件的一個好處就是合併多個對象的渲染,從而下降DrawCalls ,保證遊戲幀數。

  四、Tris 和 Draw Calls

  預覽的時候,可點開 Stats,查看圖形渲染的開銷狀況。特別注意 Tris 保持在 7.5k 如下,有待考證。

  Draw Calls 保持在 20 如下,有待考證。

  2,FPS,每一秒遊戲執行的幀數,這個數值越小,說明遊戲越卡。

  3,Render Textures 渲染的圖片佔用內存大小。

  4,VRAM usage 顯存的使用狀況,VRAM總大小取決於你的顯卡的顯存。

  二,代碼優化

  1. 儘可能避免每幀處理

  好比:

  function Update() { DoSomeThing(); }

  可改成每5幀處理一次:

  function Update() { if(Time.frameCount % 5 == 0) { DoSomeThing(); } }

  2. 定時重複處理用 InvokeRepeating 函數實現

  好比,啓動0.5秒後每隔1秒執行一次 DoSomeThing 函數:

  function Start() { InvokeRepeating(「DoSomeThing」, 0.5, 1.0); }

  3. 優化 Update, FixedUpdate, LateUpdate 等每幀處理的函數

  函數裏面的變量儘可能在頭部聲明。

  好比:

  function Update() { var pos: Vector3 = transform.position; }

  可改成

  private var pos: Vector3; function Update(){ pos = transform.position; }

  4. 主動回收垃圾

  給某個 GameObject 綁上如下的代碼:

  function Update() { if(Time.frameCount % 50 == 0) { System.GC.Collect(); } }

  5. 優化數學計算

  好比,若是能夠避免使用浮點型(float),儘可能使用整形(int),儘可能少用複雜的數學函數好比 Sin 和 Cos 等等

  6,減小固定增量時間

   將固定增量時間值設定在0.04-0.067區間(即,每秒15-25幀)。您能夠經過Edit->Project Settings->Time來改變這個值。這樣作下降了FixedUpdate函數被調用的頻率以及物理引擎執行碰撞檢測與剛體更新的頻率。若是 您使用了較低的固定增量時間,而且在主角身上使用了剛體部件,那麼您能夠啓用插值辦法來平滑剛體組件。

  7,減小GetComponent的調用

  使用 GetComponent或內置組件訪問器會產生明顯的開銷。您能夠經過一次獲取組件的引用來避免開銷,並將該引用分配給一個變量(有時稱爲「緩存」的引用)。例如,若是您使用以下的代碼:

css

[AppleScript] 純文本查看 複製代碼
  function Update () {

  transform.Translate(0, 1, 0);

  }


  經過下面的更改您將得到更好的性能:

[AppleScript] 純文本查看 複製代碼
  var myTransform : Transform;

  function Awake () {

  myTransform = transform;

  }

  function Update () {

  myTransform.Translate(0, 1, 0);

  }


  8,避免分配內存

  您應該避免分配新對象,除非你真的須要,由於他們再也不在使用 時,會增長垃圾回收系統的開銷。您能夠常常重複使用數組和其餘對象,而不是分配新的數組或對象。這樣作好處則是儘可能減小垃圾的回收工做。同時,在某些可能 的狀況下,您也可使用結構(struct)來代替類(class)。這是由於,結構變量主要存放在棧區而非堆區。由於棧的分配較快,而且不調用垃圾回收 操做,因此當結構變量比較小時能夠提高程序的運行性能。可是當結構體較大時,雖然它仍可避免分配/回收的開銷,而它因爲「傳值」操做也會致使單獨的開銷, 實際上它可能比等效對象類的效率還要低。

  9,使用iOS腳本調用優化功能

  UnityEngine 命名空間中的函數的大多數是在 C/c + +中實現的。從Mono的腳本調用 C/C++函數也存在着必定的性能開銷。您可使用iOS腳本調用優化功能(菜單:Edit->Project Settings->Player)讓每幀節省1-4毫秒。此設置的選項有:

  Slow and Safe – Mono內部默認的處理異常的調用

  Fast and Exceptions Unsupported –一個快速執行的Mono內部調用。不過,它並不支持異常,所以應謹慎使用。它對於不須要顯式地處理異常(也不須要對異常進行處理)的應用程序來講,是一個理想的候選項。

  10,

  優化垃圾回收

  如上文所述,您應該儘可能避免分配操做。可是,考慮到它們是不能徹底杜絕的,因此咱們提供兩種方法來讓您儘可能減小它們在遊戲運行時的使用:

  若是堆比較小,則進行快速而頻繁的垃圾回收

   這一策略比較適合運行時間較長的遊戲,其中幀率是否平滑過渡是主要的考慮因素。像這樣的遊戲一般會頻繁地分配小塊內存,但這些小塊內存只是暫時地被使 用。若是在iOS系統上使用該策略,那麼一個典型的堆大小是大約 200 KB,這樣在iPhone 3G設備上,垃圾回收操做將耗時大約 5毫秒。若是堆大小增長到1 MB時,該回收操做將耗時大約 7ms。所以,在普通幀的間隔期進行垃圾回收有時候是一個不錯的選擇。一般,這種作法會讓回收操做執行的更加頻繁(有些回收操做並非嚴格必須進行的), 但它們能夠快速處理而且對遊戲的影響很小:

[AppleScript] 純文本查看 複製代碼
  if (Time.frameCount % 30 == 0)

  {

  System.GC.Collect();

  }


  可是,您應該當心地使用這種技術,而且經過檢查Profiler來確保這種操做確實能夠下降您遊戲的垃圾回收時間

  若是堆比較大,則進行緩慢且不頻繁的垃圾回收

  這一策略適合於那些內存分配 (和回收)相對不頻繁,而且能夠在遊戲停頓期間進行處理的遊戲。若是堆足夠大,但尚未大到被系統關掉的話,這種方法是比較適用的。可是,Mono運行時會盡量地避免堆的自動擴大[url=http://www.unitymanual.com/forum-develop-1.html]unity 3d開發心得[/url] 所以,您須要經過在啓動過程當中預分配一些空間來手動擴展堆(ie,你實例化一個純粹影響內存管理器分配的「無用」對象):

[AppleScript] 純文本查看 複製代碼
  function Start() {

  var tmp = new System.Object[1024];

  // make allocations in smaller blocks to avoid them to be treated in a special way, which is designed for large blocks

  for (var i : int = 0; i < 1024; i++)

  tmp[i] = new byte[1024];

  // release reference

  tmp = null;

  }


  遊戲中的暫停是用來對堆內存進行回收,而一個足夠大的堆應該不會在遊戲的暫停與暫停之間被徹底佔滿。因此,當這種遊戲暫停發生時,您能夠顯式請求一次垃圾回收:

  System.GC.Collect();

  另外,您應該謹慎地使用這一策略並時刻關注Profiler的統計結果,而不是假定它已經達到了您想要的效果。

  三,模型

  1,壓縮 Mesh

  導入 3D 模型以後,在不影響顯示效果的前提下,最好打開 Mesh Compression。

  Off, Low, Medium, High 這幾個選項,可酌情選取。

  2,避免大量使用 Unity 自帶的 Sphere 等內建 Mesh

  Unity 內建的 Mesh,多邊形的數量比較大,若是物體不要求特別圓滑,可導入其餘的簡單3D模型代替。
        遊戲蠻牛:http://www.unitymanual.com

 

 

 

 

 

最簡單的優化建議:

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中顯示的RenderTextureTexture2D.html

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

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

MIPMAps(多重紋理格式):

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

[Unity3D]圖形渲染優化、渲染管線優化、圖形性能優化
     
         
 
 
 
 
轉載請留下本文原始連接,謝謝。本文會不按期更新維護,最近更新於2013.11.09
 
主要內容也能夠參考:
http://docs.unity3d.com/Documentation/Manual/OptimizingGraphicsPerformance.html
 
最簡單的優化建議:
 
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)和內存帶寬(MemoryBandwidth)的限制,若是你的遊戲在低質量表現的狀況下會快不少,那麼,你極可能須要限制你在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 callbatching)。具體方法和注意事項查看如下連接:
 
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 、 OcclusionCulling
 
LOD (Level Of Detail)是很經常使用的3D遊戲技術了,其功能理解起來則是至關於多重紋理貼圖。在以在屏幕中顯示模型大小的比例來判斷使用高或低層次的模型來減小對GPU的傳輸數據,和減小GPU所須要的頂點計算。
 
攝像機分層距離剔除(Per-Layer CullDistances):爲小物體標識層次,而後根據其距離主攝像機的距離判斷是否須要顯示。
 
遮擋剔除(OcclusionCulling)其實就是當某個物體在攝像機前被另一個物體徹底擋住的狀況,擋住就不發送給GPU渲染,從而直接下降DRAWCALL。不過有些時候在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內(固然還要看具體的需求)。
 
http://docs.unity3d.com/Documentation/Manual/ModelingOptimizedCharacters.html
相關文章
相關標籤/搜索