乾貨:Unity遊戲開發圖片紋理壓縮方案
原文連結:http://www.jianshu.com/p/f7c3741f22af
Unity3d引擎對紋理的處理是智慧的:不論你放入的是PNG,PSD還是TGA,它們都會被自動轉換成Unity自己的Texture2D格式。
在Texture2D的設定選項中,你可以針對不同的平臺,設定不同的壓縮格式,如iOS設定成PVRTC4,Android平臺設定成RGBA16等。嗯,非常的智慧。
但是,在一些進階的使用中,一些情況是難以滿足的。比如,我們NGUI的圖集中,在Android平臺,使用ETC1紋理+Alpha通道圖的方式;IOS平臺,使用PVRTC4的紋理;部分要求清晰度較高的,使用RGBA16,但是使用RGBA16的漸變顯示圖片卻慘不忍睹;一些要求高保真的,則需要直接使用RGBA32格式。有些時候,單純的Unity紋理管理已經無法滿足我們的需求了,需要做一下額外工作。
總結一下我自己的紋理壓縮方案:
紋理壓縮的策略手遊開發(Android/IOS)中,我會使用3個級別的壓縮程度:高清晰無壓縮、中清晰中壓縮、低清晰高壓縮;4種壓縮方法:RGBA32, RGBA16+Dithering,ETC1+Alpha,PVRTC4。一般足夠應付大部分的需求了。
高清晰無壓縮 - RGBA32
RGBA32等同於原圖了,優點是清晰、與原圖一致,缺點是記憶體佔用十分大;對於一些美術要求最好清晰度的圖片,是首選。
要注意一些png圖片,在硬碟中佔用幾KB,怎麼在Unity中顯示卻變大?因為Unity顯示的是Texture大小,是實際執行時佔用記憶體的大小,而png卻是一種壓縮顯示格式;可以這樣理解,png類似於zip格式,是一個壓縮檔案,只不過在執行時會自動解壓解析罷了。
中清晰中壓縮 - RGBA16 +
Dithering
RGBA16+Dithering
Unity
RGBA32 - 高清晰無壓縮.png
RGBA32等同於原圖了,優點是清晰、與原圖一致,缺點是記憶體佔用十分大;對於一些美術要求最好清晰度的圖片,是首選。
要注意一些png圖片,在硬碟中佔用幾KB,怎麼在Unity中顯示卻變大?因為Unity顯示的是Texture大小,是實際執行時佔用記憶體的大小,而png卻是一種壓縮顯示格式;可以這樣理解,png類似於zip格式,是一個壓縮檔案,只不過在執行時會自動解壓解析罷了。
中清晰中壓縮 - RGBA16 +
Dithering
RGBA16+Dithering
Unity
RGBA16,不抖動處理的漸變圖片慘不忍睹
既然叫RGBA16,自然就是RGBA32的閹割版。
對於一些採用漸變的圖片,從RGBA32轉換成RGBA16,能明顯的看出顏色的層疊變化,如上圖。
採用Floyd
Steinberg抖動處理後,除非放大,否則肉眼基本看不出區別
RGBA16的優點,記憶體佔用是RGBA32的1/2;搭配上Dithering抖動,在原尺寸下看清晰度一模一樣;
缺點,Unity原生不支援Dithering抖動,需要自己做工具對圖片做處理;對於需要放大、拉伸的圖片,Dithering抖動的支援不好,會有非常明顯的顆粒感。
如何進行Dithering抖動?
Texture
Packer工具中Image Format選擇RGBA4444,Dithering選擇FloydSteinberg
在我的專案中,TexturePacker具有非常重要的作用,像UI的圖集生成,預先生成好正方形的IOS PVRTC4圖集和非正方形的Android ETC1圖集、 縮放原圖50%等工作都由TexturePacker完成。
同樣,對影象進行抖動處理,也是預先在TexturePacker使用FloydSteinberg演算法進行影象抖動,再在Unity中匯入使用。
TexturePacker提供命令列工具,可以做成自動化的工具。具體方法這裡不詳述。
RGB16
而RGB16,是主要針對一些,不帶透明通道,同時長寬又不是2的次方的圖片;對於這些圖片,使用RGB16可以降低一半的記憶體,但是效果會略遜於RGB32。
當然了,RGB16其實也是可以搭配抖動,也能提升顯示效果;但同樣的Dithering抖動對拉伸放大是不友好的。
低清晰高壓縮
- ETC1+Alpha/PVRTC4
很多初學者都會疑惑,為什麼遊戲開發中經常看到一些圖片,需要設定成2的次方?因為像ETC1、PVRTC4等這類在記憶體中無需解壓、直接被GPU支援的格式,佔用記憶體極低,而且效能效率也是最好的。
但是,相對RGBA32,還是能肉眼看出質量有所下降的。
ETC1
ETC1+Alpha一般應用在Android版的UI圖集中,ETC1不帶透明通道,所以需要外掛一張同樣是ETC1格式的Alpha通道圖。方法是,在原RGBA32的原圖中,提取RGB生成第一張ETC1,再提取A通道,填充另一張ETC1的R通道;遊戲執行時,Shader將兩張ETC1圖片進行混合。
生成Alpha通道圖的方法可參考:
http://blog.csdn.net/u010153703/article/details/45502895
要配合ETC1+Alpha,還需要Shader支援,這裡提供參考直接修改NGUI的Unlit/Transparent With Colored的Shader。
Paste_Image.png
PVRTC4
PVRTC4在Unity中是直接支援的,不過要注意的細節是,它必須是二次方正方形;也就是說,長寬在二次方的同時,還必須要相等。
幾種紋理格式的對比
在專案中,儘可能是使用ETC1和PVRTV4等GPU直接支援的圖片格式,不僅記憶體佔用低、效能也更好;當出現質量不及格時,再逐步的提升壓縮格式,來滿足需要。
- 記憶體佔用,相對於RGBA32做比較
- 質量星級,更多是本人感受,僅供參考
因此,實際專案中要混搭各種紋理格式。
文/公的Kelly
原文連結:http://www.jianshu.com/p/f7c3741f22af