unity3d優化總結篇 (難度3 推薦5)

原文地址:html

http://www.cnblogs.com/harlan1009/p/3970584.htmlandroid

優化: 

1. 更新不透明貼圖的壓縮格式爲ETC 4bit,由於android市場的手機中的GPU有多種,
每家的GPU支持不一樣的壓縮格式,但他們都兼容ETC格式,

2. 對於透明貼圖,咱們只能選擇RGBA 16bit 或者RGBA 32bit。

3. 減小FPS,在ProjectSetting-> Quality中的
VSync Count 參數會影響你的FPS,EveryVBlank至關於FPS=60,EverySecondVBlank = 30;
這兩種狀況都不符合遊戲的FPS的話,咱們須要手動調整FPS,首先關閉垂直同步這個功能,而後在代碼的Awake方法裏手動設置FPS(Application.targetFrameRate = 45;)
下降FPS的好處:
1)省電,減小手機發熱的狀況;
2)能都穩定遊戲FPS,減小出現卡頓的狀況。

4. 當咱們設置了FPS後,再調整下Fixed timestep這個參數,
這個參數在ProjectSetting->Time中,目的是減小物理計算的次數,來提升遊戲性能。

5. 儘可能少使用Update LateUpdate FixedUpdate,這樣也能夠提高性能和節省電量。
多使用事件(不是SendMessage,使用本身寫的,或者C#中的事件委託)。

6. 待機時,調整遊戲的FPS爲1,節省電量。

7. 圖集大小最好不要高於1024,不然遊戲安裝以後、低端機直接崩潰、緣由是手機系統版本低於2.二、超過1000的圖集沒法讀取、致使。
2.2 以上沒有碰見這個狀況。
注意手機的RAM 與 ROM、小於 512M的手機、直接放棄機型適配。

VSCount 垂直同步
   unity3d中新建一個場景空的時候,幀速率(FPS老是很低),大概在60~70之間。
一直不太明白是怎麼回事,如今基本上明白了。我在這裏解釋一下緣由,若有錯誤,歡迎指正。
在Unity3D中當運行場景打開Profiler的時候,咱們會看到VSync 這一項佔了很大的比重。
這個是什麼呢,這個就是垂直同步,稍後再作解釋。
咱們能夠關閉VSync來提升幀速率,選擇edit->project settings->Quality。ios

<ignore_js_op>web

 


在右側面板中能夠找到VSync Count,把它選成Don't Sync。
<ignore_js_op> 
這就關閉了VSync(垂直同步),如今在運行場景看看,幀速率是否是提升不少。

如今來講說什麼是垂直同步,要知道什麼是垂直同步,必需要先明白顯示器的工做原理,
顯示器上的全部圖像都是一線一線的掃描上去的,不管是隔行掃描仍是逐行掃描,
顯示器都有兩種同步參數——水平同步和垂直同步。

什麼叫水平同步?什麼叫垂直同步?
垂直和水平是CRT中兩個基本的同步信號,水平同步信號決定了CRT畫出一條橫越屏幕線的時間,
垂直同步信號決定了CRT從屏幕頂部畫到底部,再返回原始位置的時間,
而偏偏是垂直同步表明着CRT顯示器的刷新率水平。

爲何關閉垂直同步信號會影響遊戲中的FPS數值?
若是咱們選擇等待垂直同步信號(也就是咱們平時所說的垂直同步打開),
那麼在遊戲中或許強勁的顯卡迅速的繪製完一屏的圖像,可是沒有垂直同步信號的到達,
顯卡沒法繪製下一屏,只有等85單位的信號到達,才能夠繪製。
這樣FPS天然要受到操做系統刷新率運行值的制約。

而若是咱們選擇不等待垂直同步信號(也就是咱們平時所說的關閉垂直同步),那麼遊戲中做完一屏畫面,
顯卡和顯示器無需等待垂直同步信號就能夠開始下一屏圖像的繪製,天然能夠徹底發揮顯卡的實力。
可是不要忘記,正是由於垂直同步的存在,才能使得遊戲進程和顯示器刷新率同步,使得畫面更加平滑和穩定。
取消了垂直同步信號,當然能夠換來更快的速度,可是在圖像的連續性上勢必打折扣。
這也正是不少朋友抱怨關閉垂直後發現畫面不連續的理論緣由。

合併材質球unity 3d中每倒入一次模型就多一個材質球,可個人這些模型都是共用一張貼圖的就想共用一個材質球,因此每次都要刪除再附上,很麻煩。怎麼才能合併這些材質球?
採用TexturePacking吧
一、遍歷gameobject,取出material,並根據shader來將material分類
二、調用Unity自帶的PackTextures函數來合併每一個shader分類中的material所對應的textures(PackTextures函數有缺陷,不過能夠將就用)
三、根據合併的大的texture來更新原有模型的texture、material已經uv座標值。

須要注意的是:須要合併的紋理應該是物體在場景中距離相近的,若是物體在場景中的距離較遠,
則不建議合併紋理,由於這樣作頗有可能非但起不到優化的做用,反而下降了運行效率。 

mesh合併 
分爲2種方式合併
1.自帶的合併必須勾選靜態。
<ignore_js_op> 
全部被勾選了「Static」的GameObject,其中的Mesh Filter中的mesh都會被合併到 "Combined Mesha (root: scene)" 中


2.也能夠用腳原本合併mesh 。算法

[C#]  純文本查看 複製代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
using  UnityEngine;
using  System.Collections;
 
public  class  MyClass : MonoBehaviour
{
     void  Start ()
     {
         MeshFilter [] meshFilters = GetComponentsInChildren<MeshFilter> ();
         CombineInstance[] combine = new  CombineInstance[meshFilters.Length];
 
         for  ( int  i = 0; i < meshFilters.Length; i++) {
             combine [i].mesh = meshFilters [i].sharedMesh;
             combine [i].transform = meshFilters [i].transform.localToWorldMatrix;
             meshFilters [i].gameObject.active = false ;
         }
 
             transform.GetComponent<MeshFilter> ().mesh = new  Mesh ();
             transform.GetComponent<MeshFilter> ().mesh.CombineMeshes (combine);
             transform.gameObject.active = true ;
     }
}


1. 先在 Unity 中創建 空物件 ( Empty ) 
2. 再建立2個 Cube 方塊,並放入 空物件底下 (能夠改爲你本身的模型)
3. 把 MyClass 代碼丟進 空物件上 。
4. (可選) 創建一個 Material 材質,而且丟進 空物件上
5. 執行

<ignore_js_op> 


<ignore_js_op> 
========================================分割線====================================數組

  • 角色Material數量
2-3個
  • 骨骼數量
小於30個
  • 面片數量
300-1500
  • 通常角色應該沒有IK結點
這是由於角色的動做大多數都是事先設定好的,並不須要通過IK操做來進行實時計算(Rogdoll除外),因此在模型導入時,不要將IK結點一塊兒導入。

 

二、靜態實體性能優化

  • 不要附加Animation Component
在靜態實體上附加Animation部件雖然對結果沒有影響,但卻會增長必定的CPU開銷來調用這一組件,因此儘可能去掉該組件。
  • 網格頂點數
小於500
  • UV值範圍儘可能不要超過(0, 1)區間
儘可能保證UV值不越界,這對於未來的紋理拼合優化頗有幫助。

 

三、地形app

  • 地形的分辨率大小
長寬均儘可能小於257。這是由於地形太大,會形成大量頂點數據,給你的內存帶寬形成必定的影響,在目前的ios設備中,內存帶寬是很是有限的,須要儘可能節省。同時,若是用Unity自帶的地形,必定也要使用Occlusion Culling,由於Unity的刷地形工具雖然方便,但倒是framekiller,刷過以後,你會發現drawcall增長的很是多。
  • 混合紋理數量
不要超過4。地形的混合操做是很耗時的,應該儘可能避免。能合併的紋理儘可能合併。

 

四、紋理less

  • 紋理格式
建議png或tga。不用轉成ios硬件支持的PVRTC格式,由於Unity在發佈時會幫你自動轉的。
  • 紋理尺寸
長寬小於1024。同時應該儘量地小,夠用就好,以保證紋理對內存帶寬的影響達到最小。
  • 支持Mipmap
建議生成Mipmap。雖然這種作法會增長一些應用程序的大小,但在遊戲運行時,系統會根據需求應用Mipmap來渲染,從而減小內存帶寬。
  • 檢查Alpha值
若是紋理的alpha通道均爲1,則用RGB的24位紋理來代替RGBA的32位紋理。(聽說Unity內部會進行自動檢測)

 

五、光源編輯器

  • 光源「Important」個數
建議1個,通常爲方向光。「Important」個數應該越小越少。個數越多,drawcall越多。
  • Pixel Light數目
1-2個。

 

六、粒子特效

  • 屏幕上的最大粒子數
建議小於200個粒子。
  • 每一個粒子發射器發射的最大粒子數
建議不超過50個。
  • 粒子大小
若是能夠的話,粒子的size應該儘量地小。由於Unity的粒子系統的shader不管是alpha test仍是alpha blending都是一筆不小的開銷。同時,對於很是小的粒子,建議粒子紋理去掉alpha通道。
  • 儘可能不要開啓粒子的碰撞功能。
很是耗時。

 

七、音頻

  • 遊戲中播放時間較長的音樂(如背景音樂)
使用.ogg或.mp3的壓縮格式。
  • 較短音樂(如槍聲)
使用.wav和.aif的未壓縮音頻格式。

 

八、相機

  • 裁剪平面
將遠平面設置成合適的距離。遠平面過大會將一些沒必要要的物體加入渲染,下降效率。
  • 根據不一樣的物體設置不一樣的遠裁剪平面
Unity提供了能夠根據不一樣的layer來設置不一樣的view distance,因此咱們能夠實現將物體進行分層,大物體層設置的可視距離大些,而小物體層能夠設置地小些,另外,一些開銷比較大的實體(如粒子系統)能夠設置得更小些等等。

 

九、碰撞

  • 儘可能不用MeshCollider
若是能夠的話,儘可能不用MeshCollider,以節省沒必要要的開銷。若是不能避免的話,儘可能用減小Mesh的面片數,或用較少面片的代理體來代替。

 

十、其餘

  • Drawcall
儘量地減小Drawcall的數量。IOS設備上建議不超過100。減小的方法主要有以下幾種:Frustum Culling,Occlusion Culling,Texture Packing。Frustum Culling是Unity內建的,咱們須要作的就是尋求一個合適的遠裁剪平面;Occlusion Culling,遮擋剔除,Unity內嵌了Umbra,一個很是好OC庫。但Occlusion Culling也並非放之四海而皆準的,有時候進行OC反而比不進行還要慢,建議在OC以前先肯定本身的場景是否適合利用OC來優化;Texture Packing,或者叫Texture Atlasing,是將同種shader的紋理進行拼合,根據Unity的static batching的特性來減小draw call。建議使用,但也有弊端,那就是必定要將場景中距離相近的實體紋理進行拼合,不然,拼合後極可能會增長每幀渲染所需的紋理大小,加大內存帶寬的負擔。這也就是爲何會出現「DrawCall降了,渲染速度也變慢了」的緣由。

 

  • 非運動物體儘可能打上Static標籤
Unity在運行時會對static物體進行自動優化處理,因此應該儘量將非運行實體勾上static標籤。

 

  • 場景中儘量地使用prefab
儘量地使用prefab的實例化物體,以下降內存帶寬的負擔。檢查實體的PrefabType,儘可能將其變成PrefabInstance,而不是ModelPrefabInstance。



========================================分割線==================================== 

移動平臺相對於PC機,具備體積小,計算弱,帶寬少的特色。

所以作手機遊戲的開發,優化的方向,與力度對比PC遊戲都有所區別。

 

必需要作到優化流程,合理利用資源。

目前在手機上面,還不可以像PC遊戲那樣追求高質量渲染效果,爲了讓手機不那麼容易發燙,還要控制cpu,gpu,不能讓他們全速運算。

 

材質方面:

紋理方面,建議使用壓縮紋理,

Android上面使用ETC1,蘋果上面使用PVRTC。

 

UV座標控制在0到1之間,人物模型面數控制在1500內,骨骼控制在30個之內。

場景中使用一個主光(不能再多了)。

 

儘可能減小alphaTest和alphaBlend材質的使用。在手機上,這是很殺效率的。

 

骨骼動畫方面:

在動畫方面能夠考慮不使用插值,固定的幀率的動畫。

若是要作插值,考慮使用四元數(表示旋轉)和向量(表示位移)來作插值。

四元數作插值速度比矩陣來的快,Slerp提供了平滑插值。



========================================分割線==================================== 

優化的常規技巧
剖析你的遊戲。
不要花費時間來優化那些晦澀的代碼或者縮減圖形文件的大小,除非這是你遊戲的瓶頸。
第一次剖析你的遊戲將會使你發現你遊戲的瓶頸。Apple's Shark是一個很好的用來剖析基於OpenGL的程序的工具。
再次剖析你的遊戲。
優化以後不要忘記再剖析一次你的遊戲,這樣能夠檢查你所作的優化是否達到了預期的效果。
固然,這樣作也可能會使你發現更多的瓶頸。
流程第1、性能第二。花費時間來使你遊戲的建立儘量地流暢。
儘量快地修正遊戲中的錯誤將會使你後期更容易優化你的遊戲。
在Scene View中測試場景。
這樣作將會使你清楚瞭解這個場景中的物體或者附加在物體上的腳本是否下降了遊戲性能。
若是Scene View反應遲鈍,那麼有多是圖形方面的緣由,若是Scene View反應不遲鈍,那麼瓶頸可能出在腳本或者物理系統上。
禁用指定遊戲物體。
在play模式下,嘗試禁用並啓用遊戲物體來排查出遊戲慢的緣由。

網格
若是可能的話,把相鄰的物體(網格)合併爲一個只有一個材質的物體(網格)。好比,你的遊戲中包含一個桌子,上面有一堆東西,你徹底能夠在3D程序中將它們合併在一塊兒(這可能也須要你將這些物體的紋理合併爲一個大的紋理集)。減小須要渲染的物體的數量能夠極大地提升遊戲性能。

不要有沒必要要的網格。
若是你的遊戲場景中有一我的物,那麼他應該是一個網格。若是你有一個船,那麼它也應該只是一個網格。
每個網格只用一種材質。
使用極少的面數的網格(好比500個多邊形如下)。
最好把你人物的三角面數量控制在1500-2000個之間。
這個數量能夠說是遊戲質量和性能之間一個均衡值。若是你的模型有四邊形,那麼在導入模型的時候,引擎將會把每一個四邊形變爲兩個三角形。

光照
像素光。
像素光可讓你的遊戲看起來效果很牛逼,可是不要使用過多的像素光。
在你的遊戲中可使用質量管理器來調節像素光的數量來取得一個性能和質量的均衡點.

性能佔用順序:聚光燈>點光源>平行光。
一個好的點亮場景的方法就是先獲得你想要的效果,而後看看哪些光更重要;
在保持光效的前提下看看哪些光能夠去掉。

點光源和聚光燈隻影響它們範圍內的網格。
若是一個網格處於點光源或者聚光燈的照射範圍以外,而且光源的attenuate開關是打開的,那麼這個網格將不會被光源所影響,這樣就能夠節省性能開銷。
這樣作理論上來說可使用不少小的點光源並且依然能有一個好的性能,由於這些光源隻影響一小部分物體。
一個網格在有8個以上光源影響的時候,只響應前8個最亮的光源。

貼圖
在外觀不變的前提下,貼圖大小越小越好。
若是你的顯卡的顯存不夠大的話,你遊戲中的貼圖將會被轉存到系統內存中,在顯卡調用它們的時候再傳到顯卡中。
對於比較新的電腦來講,內存和顯卡之間有足夠的帶寬來達到一個很好的性能;
若是你很無恥地用了巨多的大圖片的話,在低顯存的電腦上運行你的遊戲的時候,你的遊戲必然會掛掉。
卻是沒有必要在圖形編輯軟件中調整貼圖的大小。你能夠在unity導入貼圖的時候進行調整。

不要使用低質量的圖片。
在小播放界面的遊戲中使用低質量的jpeg圖片或者低色彩的png圖片亦或是gif圖片沒什麼問題。
在發佈遊戲的時候,引擎會自動壓縮這些圖片,多重壓縮和解壓將會下降圖片的質量,因此最好保持貼圖文件的分辨率爲原始分辨率。
這樣就會減小多重壓縮和解壓所致使的圖片失真現象。

Shaders
多重效果的shader就比看起來樣式很單一的shader要更耗費資源。
一樣在一個擁有貼圖和光反射的物體上,使用VertexLit Diffuse shader無疑是最省資源的。


========================================分割線==================================== 

在美術製做場景的過程當中,會使用到大量的粒子系統。
好比場景中的火把。在咱們的一個地下城場景中,美術們放置了大量的火把。整個場景中的各個地方,有100來個火把。

unity中,在攝像機範圍外的粒子系統雖然不會被繪製。
可是update是一直持續的。這也就意味着,這100多個火把,不管是否可見都在更新。

這個設計應該是很不合理的,在我看過的其餘引擎中,都會有一個開關,來控制不可見的粒子系統是否須要update。
有的粒子系統在不可見的時候須要更新,好比爆炸。有的不須要更新,好比火堆火把。

爲了不沒必要要的update開銷,尤爲是最後遊戲是要發佈到頁遊平臺(web player只能使用一個cpu的核)。
因而寫了一個腳本,控制不可見的粒子系統就不更新。

該腳本主要是用到了2個MonoBehaviour的函數。
OnBecameInvisible() 當變爲不可見   和   OnBecameVisible() 當變成可見。 

要這2個函數起做用的前提是,該GameObject綁定了MeshRender組件。
因此,咱們要在粒子系統的GameObject放置在一個GameObject  下,且給該GameObject綁定一個MeshRender 與 MeshFilter。
MeshFilter中的mesh能夠隨便找個cube。

在Start() 的時候,把最GameObject的scale設置爲很小,以保證該cube不被看見。
其實遍歷全部的child,把active設置爲false。

在OnBecameVisible 中 遍歷全部child,把active設置爲true。
在OnBecameInvisible中 遍歷全部child,把active設置爲false。


========================================分割線==================================== 

Unity 性能優化 Draw Call 

Unity(或者說基本全部圖形引擎)生成一幀畫面的處理過程大體能夠這樣簡化描述:引擎首先通過簡單的可見性測試,肯定攝像機能夠看到的物體,而後把這些物體的頂點(包括本地位置、法線、UV等),索引(頂點如何組成三角形),變換(就是物體的位置、旋轉、縮放、以及攝像機位置等),相關光源,紋理,渲染方式(由材質/Shader決定)等數據準備好,而後通知圖形API——或者就簡單地看做是通知GPU——開始繪製,GPU基於這些數據,通過一系列運算,在屏幕上畫出成千上萬的三角形,最終構成一幅圖像。 在Unity中,每次引擎準備數據並通知GPU的過程稱爲一次Draw Call。這一過程是逐個物體進行的,對於每一個物體,不僅GPU的渲染,引擎從新設置材質/Shader也是一項很是耗時的操做。所以每幀的Draw Call次數是一項很是重要的性能指標,對於iOS來講應儘可能控制在20次之內,這個值能夠在編輯器的Statistic窗口看到。 Unity內置了Draw Call Batching技術,從名字就能夠看出,它的主要目標就是在一次Draw Call中批量處理多個物體。只要物體的變換和材質相同,GPU就能夠按徹底相同的方式進行處理,便可以把它們放在一個Draw Call中。Draw Call Batching技術的核心就是在可見性測試以後,檢查全部要繪製的物體的材質,把相同材質的分爲一組(一個Batch),而後把它們組合成一個物體(統一變換),這樣就能夠在一個Draw Call中處理多個物體了(其實是組合後的一個物體)。 但Draw Call Batching存在一個缺陷,就是它須要把一個Batch中的全部物體組合到一塊兒,至關於建立了一個與這些物體加起來同樣大的物體,與此同時就須要分配相應大小的內存。這不只會消耗更多內存,還須要消耗CPU時間。特別是對於移動的物體,每一幀都得從新進行組合,這就須要進行一些權衡,不然得不償失。但對於靜止不動的物體來講,只須要進行一次組合,以後就能夠一直使用,效率要高得多。 Unity提供了Dynamic Batching和Static Batching兩種方式。Dynamic Batching是徹底自動進行的,不須要也沒法進行任何干預,對於頂點數在300之內的可移動物體,只要使用相同的材質,就會組成Batch。Static Batching則須要把靜止的物體標記爲Static,而後不管大小,都會組成Batch。如前文所說,Static Batching顯然比Dynamic Batching要高效得多,因而,Static Batching功能是收費的…… 要有效利用Draw Call Batching,首先是儘可能減小場景中使用的材質數量,即儘可能共享材質,對於僅紋理不一樣的材質能夠把紋理組合到一張更大的紋理中(稱爲Texture Atlasing)。而後是把不會移動的物體標記爲Static。此外還能夠經過CombineChildren腳本(Standard Assets/Scripts/Unity Scripts/CombineChildren)手動把物體組合在一塊兒,但這個腳本會影響可見性測試,由於組合在一塊兒的物體始終會被看做一個物體,從而會增長GPU要處理的幾何體數量,所以要當心使用。 對於複雜的靜態場景,還能夠考慮自行設計遮擋剔除算法,減小可見的物體數量同時也能夠減小Draw Call。 總之,理解Draw Call和Draw Call Batching原理,根據場景特色設計相應的方案來儘可能減小Draw Call次數纔是王道,其它方面亦然。 Draw Call Batching (繪製調用批處理) To draw an object on the screen, the engine has to issue a draw call to the graphics API (OpenGL ES in the case of iOS). Every single draw call requires a significant amount of work on the part of the graphics API, causing significant performance overhead on the CPU side. 在屏幕上渲染物體,引擎須要發出一個繪製調用來訪問圖形API(iOS系統中爲OpenGL ES)。 每一個繪製調用須要進行大量的工做來訪問圖形API,從而致使了CPU方面顯著的性能開銷。 Unity combines a number of objects at runtime and draws them together with a single draw call. This operation is called "batching". The more objects Unity can batch together, the better rendering performance you will get. Unity在運行時能夠將一些物體進行合併,從而用一個繪製調用來渲染他們。這一操做,咱們稱之爲「批處理」。 通常來講,Unity批處理的物體越多,你就會獲得越好的渲染性能。 Built-in batching support in Unity has significant benefit over simply combining geometry in the modeling tool (or using theCombineChildren script from the Standard Assets package). Batching in Unity happensafter visibility determination step. The engine does culling on each object individually, and the amount of rendered geometry is going to be the same as without batching. Combining geometry in the modeling tool, on the other hand, prevents effecient culling and results in much higher amount of geometry being rendered. Unity中內建的批處理機制所達到的效果要明顯強於使用幾何建模工具(或使用Standard Assets包中的CombineChildren腳本)的批處理效果。 這是由於,Unity引擎的批處理操做是在物體的可視裁剪操做以後進行的。 Unity先對每一個物體進行裁剪,而後再進行批處理,這樣可使渲染的幾何總量在批處理先後保持不變。 可是,使用幾何建模工具來拼合物體,會妨礙引擎對其進行有效的裁剪操做,從而致使引擎須要渲染更多的幾何面片。 Materials 材質 Only objects sharing the same material can be batched together. Therefore, if you want to achieve good batching, you need to share as many materials among different objects as possible. 只有擁有相同材質的物體才能夠進行批處理。 所以,若是你想要獲得良好的批處理效果,你須要在程序中儘量地複用材質和物體。 If you have two identical materials which differ only in textures, you can combine those textures into a single big texture - a process often calledtexture atlasing. Once textures are in the same atlas, you can use single material instead. 若是你的兩個材質僅僅是紋理不一樣,那麼你能夠經過 紋理拼合 操做來將這兩張紋理拼合成一張大的紋理。 一旦紋理拼合在一塊兒,你就可使用這個單一材質來替代以前的兩個材質了。 If you need to access shared material properties from the scripts, then it is important to note that modifyingRenderer.material will create a copy of the material. Instead, you should useRenderer.sharedMaterial to keep material shared. 若是你須要經過腳原本訪問複用材質屬性,那麼值得注意的是改變Renderer.material將會形成一份材質的拷貝。 所以,你應該使用Renderer.sharedMaterial來保證材質的共享狀態。 Dynamic Batching 動態批處理 Unity can automatically batch moving objects into the same draw call if they share the same material. 若是動態物體共用着相同的材質,那麼Unity會自動對這些物體進行批處理。 Dynamic batching is done automatically and does not require any additional effort on your side. 動態批處理操做是自動完成的,並不須要你進行額外的操做。 Tips: 提醒: 一、      Batching dynamic objects has certain overheadper vertex, so batching is applied only to meshes containing less than900 vertex attributes in total.              批處理動態物體須要在每一個頂點上進行必定的開銷,因此動態批處理僅支持小於900頂點的網格物體。 二、      If your shader is using Vertex Position, Normal and single UV, then you can batch up to 300 verts and if your shader is using Vertex Position, Normal, UV0, UV1 and             Tangent, then only 180 verts.             Please note: attribute count limit might be changed in future             若是你的着色器使用頂點位置,法線和UV值三種屬性,那麼你只能批處理300頂點如下的物體; 若是你的着色器須要使用頂點位置,法線,UV0,UV1和切向量,那你只             能批處理180頂點如下的物體。             請注意:屬性數量的限制可能會在未來進行改變。 四、      Don't use scale. Objects with scale (1,1,1) and (2,2,2) won't batch.             不要使用縮放尺度(scale)。分別擁有縮放尺度(1,1,1)和(2,2,2)的兩個物體將不會進行批處理。 五、      Uniformly scaled objects won't be batched with non-uniformly scaled ones.             統一縮放尺度的物體不會與非統一縮放尺度的物體進行批處理。            Objects with scale (1,1,1) and (1,2,1) won't be batched. On the other hand (1,2,1) and (1,3,1) will be.            使用縮放尺度(1,1,1)和 (1,2,1)的兩個物體將不會進行批處理,可是使用縮放尺度(1,2,1)和(1,3,1)的兩個物體將能夠進行批處理。 六、     Using different material instances will cause batching to fail.            使用不一樣材質的實例化物體(instance)將會致使批處理失敗。 七、     Objects with lightmaps have additional (hidden) material parameter: offset/scale in lightmap, so lightmapped objects won't be batched (unless they point to same            portions of lightmap)            擁有lightmap的物體含有額外(隱藏)的材質屬性,好比:lightmap的偏移和縮放係數等。因此,擁有lightmap的物體將不會進行批處理(除非他們指向lightmap的同一            部分)。 八、     Multi-pass shaders will break batching. E.g. Almost all unity shaders supports several lights in forward rendering, effectively doing additional pass for them            多通道的shader會妨礙批處理操做。好比,幾乎unity中全部的着色器在前向渲染中都支持多個光源,併爲它們有效地開闢多個通道。 九、     Using instances of a prefab automatically are using the same mesh and material.            預設體的實例會自動地使用相同的網格模型和材質。 Static Batching 靜態批處理 Static batching, on the other hand, allows the engine to reduce draw calls for geometry of any size (provided it does not move and shares the same material). Static batching is significantly more efficient than dynamic batching. You should choose static batching as it will require less CPU power. 相對而言,靜態批處理操做容許引擎對任意大小的幾何物體進行批處理操做來下降繪製調用(只要這些物體不移動,而且擁有相同的材質)。所以,靜態批處理比動態批處理更加有效,你應該儘可能低使用它,由於它須要更少的CPU開銷。 In order to take advantage of static batching, you need explicitly specify that certain objects are static and willnot move, rotate or scale in the game. To do so, you can mark objects as static using the Static checkbox in the Inspector: 爲了更好地使用靜態批處理,你須要明確指出哪些物體是靜止的,而且在遊戲中永遠不會移動、旋轉和縮放。想完成這一步,你只須要在檢測器(Inspector)中將Static複選框打勾便可,以下圖所示: Using static batching will require additional memory for storing the combined geometry. If several objects shared the same geometry before static batching, then a copy of geometry will be created for each object, either in the Editor or at runtime. This might not always be a good idea - sometimes you will have to sacrifice rendering performance by avoiding static batching for some objects to keep a smaller memory footprint. For example, marking trees as static in a dense forest level can have serious memory impact. 使用靜態批處理操做須要額外的內存開銷來儲存合併後的幾何數據。在靜態批處理以前,若是一些物體共用了一樣的幾何數據,那麼引擎會在編輯以及運行狀態對每一個物體建立一個幾何數據的備份。這並不老是一個好的想法,由於有時候,你將不得不犧牲一點渲染性能來防止一些物體的靜態批處理,從而保持較少的內存開銷。好比,將濃密森裏中樹設爲Static,會致使嚴重的內存開銷。 Static batching is only available in Unity iOS Advanced. 靜態批處理目前只支持Unity iOS Advanced。 備註:最近一直在研究Unity3D的性能優化問題,這段時間可能會多翻譯這方面的文章。 前兩天,MadFinger,就是當今iOS與Android上畫質最牛逼閃閃的遊戲之一——ShadowGun的開發商,使人驚異地放出了一個ShadowGun的樣例關卡以及若干可無償使用的Shader,國外同行們的分享精神真的是使人讚歎不已。原文在這裏,如下是個人一些摘錄和筆記。 首先是一些優化常識。針對圖形方面的優化主要包括三角形數量,紋理所佔內存,以及Shader,前兩項基本沒什麼好講的,針對設備機能的限制制定相應的指標便可,因此Shader就成爲了圖形性能優化的關鍵。 Alpha blending 在Unity官方文檔中講,因爲硬件緣由,在iOS設備上使用alpha-test會形成很大的性能開銷,應儘可能使用alpha-blend代替。這裏提到,在同屏使用alpha-blend的面數,尤爲是這些面所佔屏幕面積的大小,對性能也會形成很大影響。緣由是使用alpha-blend的面會形成overdraw的增長,這尤爲對低性能設備的影響很大。不過沒有購買Pro版,沒有Occlusion Culling功能的話,就沒必要顧慮這一問題了,反正overdraw是必然的。 複雜的Per-pixel shader Per-pixel shader即Fragment shader,顧名思義是要對每一個渲染到屏幕上的像素作處理的shader,若是per-pixel shader比較複雜且須要處理的像素不少時,也就是使用該shader的面佔屏幕面積很大時,對性能的影響甚至要超過alpha blending。所以複雜的per-pixel shader只適用於小物體。 下面是對幾個Shader的逐一講解: Environment specular maps(Shader Virtual Gloss Per Vertex Additive) Specular map一般都是利用貼圖的alpha通道來定義物體表面的光滑程度(反光度),這個shader的特色是per-vertex計算反光度的,有着至關不錯的效果的同時比per-pixel的shader性能要高得多。這個shader很適用於關卡環境等佔很大區域的模型。 通過優化的動態角色光照和陰影(Light probes和BRDF Shader) 傳統的Lightmaps沒法支持動態物體,對此Unity提供了Light probes技術,預先把動態物體的光照信息保存在代理對象(即Light probes)中,運行時動態物體從距離最近的Probe中獲取光照信息。 Unity自己還提供了一個效果很是棒的專爲移動設備優化過的角色Shader,支持Diffuse、Specular和Normal maps,並經過一個特殊的腳本生成貼圖用於模仿BRDF光照效果。最終產生的效果堪比次時代大做中的角色光影效果。 霧和體積光(Shader Blinking Godrays) 目前在移動設備上要開啓真正的霧效基本不可行,ShadowGun的方案是經過簡單的網格+透明貼圖(稱爲霧面)來模擬霧效。在玩家靠近時,霧面逐漸變淡,同時fog plane的頂點也會移開(即便徹底透明的alpha面也會消耗不少渲染時間)。 使用這個Shader的網格須要通過處理: 頂點的alpha值用於決定頂點是否能夠移動(在例子中0爲不可動,1爲可動)。 頂點法線決定移動的方向 而後Shader經過計算與觀察者的距離來控制霧面的淡入/淡出。 這個Shader還能夠用來作體積光和其它一些alpha效果。 飛機墜毀的濃煙效果(Shader Scroll 2 Layers Sine Alpha-blended) 經過粒子產生濃煙的代價過高,因此ShadowGun中使用了網格+貼圖動畫來製做這個效果。經過混合兩層貼圖並讓它們交錯移動來產生動畫效果。其中頂點alpha值用於讓網格的邊緣看起來比較柔和,同時使用頂點顏色來模擬從火焰到煙霧的過渡效果。 帶動態效果的天空盒(Shader Scroll 2 Layers Multiplicative) 經過兩張貼圖的混合和移動產生雲的動態效果。 旗幟和衣服的飄動效果(Shader Lightmap + Wind) 一樣利用頂點alpha值決定哪些頂點能夠移動,而後shader的參數用於調整擺動的方向和速度。 =======================分割線======================== 1、程序方面   0一、務必刪除腳本中爲空或不須要的默認方法;   0二、只在一個腳本中使用OnGUI方法;   0三、避免在OnGUI中對變量、方法進行更新、賦值,輸出變量建議在Update內;   0四、同一腳本中頻繁使用的變量建議聲明其爲全局變量,腳本之間頻繁調用的變量或方法建議聲明爲全局靜態變量或方法;   0五、不要去頻繁獲取組件,將其聲明爲全局變量;   0六、數組、集合類元素優先使用Array,其次是List;   0七、腳本在不使用時腳本禁用之,須要時再啓用;   0八、可使用Ray來代替OnMouseXXX類方法;   0九、須要隱藏/顯示或實例化來回切換的對象,儘可能不要使用SetActiveRecursively或active,而使用將對象遠遠移出相機範圍和移回原位的作法;   十、儘可能少用模運算和除法運算,好比a/5f,必定要寫成a*0.2f。   十一、對於不常常調用或更改的變量或方法建議使用Coroutines & Yield;   十二、儘可能直接聲明腳本變量,而不使用GetComponent來獲取腳本; iPhone   1三、儘可能使用整數數字,由於iPhone的浮點數計算能力不好;   1四、不要使用原生的GUI方法;   1五、不要實例化(Instantiate)對象,事先建好對象池,並使用Translate「生成」對象;   2、模型方面   0一、合併使用同貼圖的材質球,合併使用相同材質球的Mesh;   0二、角色的貼圖和材質球只要一個,若必須多個則將模型離分離爲多個部分;   0二、骨骼系統不要使用太多;   0三、當使用多角色時,將動畫單獨分離出來;   0四、使用層距離來控制模型的顯示距離;   0五、陰影其實包含兩方面陰暗和影子,建議使用實時影子時把陰暗效果烘焙出來,不要使用燈光來調節光線陰暗。   0六、少用像素燈和使用像素燈的Shader;   0八、若是硬陰影能夠解決問題就不要用軟陰影,而且使用不影響效果的低分辨率陰影;   0八、實時陰影很耗性能,儘可能減少產生陰影的距離;   0九、容許的話在大場景中使用線性霧,這樣可使遠距離對象或陰影不易察覺,所以能夠經過減少相機和陰影距離來提升性能;   十、使用圓滑組來儘可能減小模型的面數;   十一、項目中若是沒有燈光或對象在移動那麼就不要使用實時燈光;   十二、水面、鏡子等實時反射/折射的效果單獨放在Water圖層中,而且根據其實時反射/折射的範圍來調整;   1三、碰撞對效率的影響很小,但碰撞仍是建議使用Box、Sphere碰撞體;   1四、建材質球時儘可能考慮使用Substance;   1五、儘可能將全部的實時反射/折射(如水面、鏡子、地板等等)都集合成一個面;   1六、假反射/折射沒有必要使用過大分辨率,通常64*64就能夠,不建議超過256*256;   1七、須要更改的材質球,建議實例化一個,而不是使用公共的材質球;   1八、將不須射線或碰撞事件的對象置於IgnoreRaycast圖層;   1九、將水面或相似效果置於Water圖層   20、將透明通道的對象置於TransparentFX圖層;   2一、養成良好的標籤(Tags)、層次(Hieratchy)和圖層(Layer)的條理化習慣,將不一樣的對象置於不一樣的標籤或圖層,三者有效的結合將很方便的按名稱、類別和屬性來查找;   2二、經過Stats和Profile查看對效率影響最大的方面或對象,或者使用禁用部分模型的方式查看問題到底在哪兒;   2三、使用遮擋剔除(Occlusion Culling)處理大場景,一種較原生的類LOD技術,而且可以「分割」做爲總體的一個模型。 3、其它   場景中若是沒有使用燈光和像素燈,就不要使用法線貼圖,由於法線效果只有在有光源(Direct Light/Point Light/Angle Light/Pixel Light)的狀況下才有效果。
相關文章
相關標籤/搜索