unity紋理總結,unity紋理
轉載請註明出處
我們知道手遊的表現力和美術密不可分,美術資源的濫用往往會導致大量的美術返工。所以根據遊戲的需要制定合理的美術規格十分重要的。寫這篇文章的目的在於解決兩個問題。第一,美術作圖有怎麼樣的規範,第二,圖片unity怎麼處理最好。
因為我們項目是2D項目,很少涉及3D模型,我們這裡的美術資源就特指2D Texture。
特別的,我們在這裡只研究texture type為sprite 的情況。因為情境中的object的component只有sprite render,而且這樣也覆蓋了gui。
首先介紹一下sprite的各個參數的簡單含義。
Sprite Mode: single獨立圖片multiple 多張有關聯圖片,可以editor切割
Packing tag: 同樣的tag可以在sprite packer中打包圖集,pro only
Pixelstounit: 單元sprite像素數量,越大越精細,預設100
Pivot: 中心點,設計到rotate的時候特別要當心
Mipmaps: 多重紋理,記憶體多1/3。做3D的話建議詳細瞭解一下
Fitermode: 被展開時候的填充模式
Maxsize: 圖片大小
Format: 紋理格式
詳情參見http://docs.unity3d.com/Manual/class-TextureImporter.html
與紋理相關的幾個方面:記憶體大小,安裝包大小和drawcall。當然還有cpu,gpu處理速度,讀取速度,這裡就不討論了,我們專心討論以上三點。
首先討論記憶體和安裝包:
Unity資源選中圖片,inspector顯示的大小,即讀入記憶體的大小。我們知道,unity可以讀取多種圖片格式,它內部會處理成為自己的專門格式,打包的時候會以assetbundle方式存放。所以,記憶體的大小依賴於紋理參數,而與圖片是什麼格式的沒有關係的。而打包成為assetbudle和記憶體相關同時也和原圖的大小相關。(其實取決於原圖大小和紋理參數)。我們可以簡單地認為記憶體佔用多了,安裝包就大。
我們首先來看一下psd圖片直接放在unity的情況。(maxsize= 1024 format = truecolor)
再看一下maxsize,format對記憶體及安裝包的影響。
上面兩份表格中1024*1024解析度的用的是同樣的圖片。我們可以看出,IOS上可以壓縮(POT圖,正方形圖)對記憶體和包大小有很大的最佳化,而format和maxsize同樣也有影響。
拋開實驗圖片不談,針對我們的遊戲(大量透明圖,色彩數廣)對原圖(大於1024*1024)的不同處理會有不同的效果:
1 maxsize調整為512。稍微失真,可以接受。
2 format由RGBA32調整為 RGBA16。完全失真,不能接受。
3 IOS壓縮為PVRTC4bit。失真非常小,完全可以接受。
4安卓壓縮為RGBA16。完全失真,不能接受。
再看一份表格,同樣的圖片表現,美術在作圖時處理為不同解析度。
其中1024*1024的圖片記憶體直接從4M到0.5M,安裝包減少4倍。優勢實在太明顯了,遺憾的是,它只支援IOS,安卓卻不可以。
再次我們討論drawcall
對於紋理首先想到的就是紋理合并。對於spritepacker,官方文檔中“For optimal performance”主要有兩點,即對於empty space和 drawcall的影響。於是對於drawcall的討論我們這裡變成對spritepacker的討論
詳情參見http://docs.unity3d.com/Manual/SpritePacker.html。
Sprite render同一材質不同紋理依舊會產生多個drawcall,而紋理的合并會減少drawcall。實際上在我們的遊戲中,攝像機範圍內的圖片總是有限的,drawcall的數量很低的,所以我們的重點不在這裡,而是spritepacker對空間的影響。
如果我們對情境中大圖小圖全圖打包會如何,情境載入時候無論用到什麼圖,都會載入圖集的記憶體,如果只用到了小圖,那麼圖集的出場無異於牛刀殺雞,這也是為什麼好多項目談經驗的時候只對GUI的圖進行圖集處理,並不是NGUI做了這份工作,以前沒有UGUI的時候沒做。
而我們的情境中基本都是背景圖,所以並不適合打包進圖集,而小的“零件圖片”卻可以被pack,多餘的載入可以換來IO的節省,這樣的規劃應該是比較合理的。
關於spritepacker其實還有個問題沒有研究清楚。Pack後的圖集是放在library的cache裡面的,library添加到SVN的ignore裡面的。按照官方說法,如果cache沒有圖集,則會再次pack。可是我們知道,pack的時候可以定製的。改變pack方式難道不儲存在一個setting檔案裡面傳上去嗎?還是在library檔案裡面被ignore掉了。前面我在思考這樣一個問題:
如果美術給的圖是NPOT的多張RGBA32圖,打包到了一個1024*1024的圖中,選擇的是定製的spritepacker,設定圖集的entry.settings.format =TextureFormat.PVRTC_RGBA4,是否意味著我對這10張都進行了合并成一個RGBA32格式的圖集然後進行對圖集PVRTC壓縮?如果是這樣的話,那麼不就是可以進一步最佳化了?不過話說回來,小圖的表現力就那麼微觀,稍微一點失真還是可以看出來的,另一方面最佳化的程度也沒有那麼大,整個等項目後期處理時候再考慮吧。
總結上面,針對我們項目的處理方案:
美術作圖:Height/width 256以片任意作圖,因為好多與UI類似。
Unity處理:選擇RGBA32做spritepacker,是否可以壓縮為PVRTC再做考量。
美術作圖:Height/width 256+的圖片,做成POT圖片
Unity處理:2048/1024的maxsize設定為1024/512(失真可接受),PVRTC壓縮。
上面主要考慮的是IOS的情況。如果安卓的話先留兩個思路吧。第一個 “目前主流的Android機型基本都支援ETC1格式壓縮。但ETC1隻能支援非Alpha通道的圖片壓縮。所以一般把Alpha通道圖分離出來,繪製到GPU顯存時,a值從Alpha圖裡擷取,無Alpha通道的圖就可以使用ETC1壓縮。”第二點依舊從maxsize做處理。以上的討論和總結都是針對我們自己的項目而言。不同項目應該有不同關注點,具體參數的理解還是要再看看文檔和經驗。希望文章能協助到有需要的同學,不對之處希望給予指正。