1 什么是壓縮紋理
在游戲中咸包,紋理不僅占據(jù)大量的包體,也占據(jù)了大量的內(nèi)存杖虾。傳統(tǒng)的圖片壓縮格式(如JPEG、PNG等)雖能減少資源大小媒熊,但是不能被GPU直接識別奇适,還是需要先加載到內(nèi)存通過CPU解碼,轉(zhuǎn)換成RGB/RGBA等能被GPU識別的格式芦鳍,才能傳送到GPU進行渲染嚷往。
為避免這些問題,壓縮紋理柠衅,指的是一種針對GPU的紋理壓縮方案皮仁,使紋理能夠直接被GPU識別并進行渲染,它具有以下優(yōu)點菲宴。
- 無需CPU解碼贷祈,節(jié)省了CPU運算,減少耗電量喝峦。
- 紋理直接被傳送到GPU势誊,避免了內(nèi)存占用,提高渲染性能谣蠢。
- 高效的壓縮算法粟耻,減少了包體大小。
2 壓縮紋理的原理
傳統(tǒng)的圖片壓縮主要目的是存儲
和傳輸
眉踱,為了盡可能的高效壓縮挤忙,使用了可變的壓縮比率,因此在解壓時需要解壓更多的像素位才能讀取某個像素的位置谈喳,不適合隨機和快速讀取册烈,也發(fā)揮不了GPU的并行處理優(yōu)勢。
而壓縮紋理使用一個固定的壓縮比率叁执,將紋理劃分成多個像素塊茄厘,每個像素塊包含2*2
或4*4
個像素,然后對每個像素塊進行壓縮谈宛,被壓縮的像素信息存儲在一個像素集合中次哈,每個像素塊的索引位置存儲在一個塊索引圖中。讀取時吆录,首先將紋理坐標(biāo)轉(zhuǎn)化為塊索引值窑滞,然后在像素集合中查找對應(yīng)的像素塊,最后在這個像素塊中找到紋理顏色值。
因為采用了固定的壓縮比率哀卫,GPU內(nèi)部可以并行處理巨坊,從而快速的解壓縮。與之相對的是此改,紋理的壓縮過程發(fā)生在程序運行之前趾撵,并不在意編碼速度,因此在壓縮時會遍歷所有可能性共啃,找到和原始像素差值最小的編碼占调,這也是紋理壓縮耗時較久的原因。
順便說一下移剪,普通圖片格式中究珊,PNG是無損壓縮,JPEG是有損壓縮纵苛。而壓縮紋理都是有損壓縮剿涮,只是在絕大部分情況下,手機上看不出來而已攻人。
3 常用的壓縮紋理格式
手機上使用壓縮紋理依賴于OpenGL ES的支持取试,OpenGL ES 2.0本身并沒有定義任何紋理壓縮格式,它僅提供 glCompressTexImage2D() 方法供應(yīng)用程序上傳壓縮紋理贝椿,壓縮紋理的格式由各個GPU廠商定義和實現(xiàn)想括。
OpenGL ES 3.0提供了壓縮紋理標(biāo)準(zhǔn),使各個平臺都可以使用同一種壓縮紋理烙博,但市面上的設(shè)備還需要很長時間才會全部過渡到OpenGL ES 3.0瑟蜈。因此,仍然需要對不同的平臺和設(shè)備使用不同的壓縮紋理格式渣窜。
手機游戲中常用的有以下格式铺根。
3.1 ETC1
ETC1把4*4
的像素塊壓縮成固定的64位編碼(8個字節(jié)),4*4
像素塊是16個像素乔宿,每個像素4字節(jié)位迂,一共占64個字節(jié),所以壓縮比是 64/8=8详瑞。但是ETC1只能存儲RGB信息掂林,不適用帶透明度的紋理,為解決這個問題坝橡,Creator在ETC1文件中額外寫入了透明度信息泻帮,即ETC1+A格式,它的壓縮比是 64/16=4计寇。
ETC1/ETC1+A需要OpenGL ES 2.0(對應(yīng)WebGL 1.0)環(huán)境锣杂,目前幾乎所有Android手機都支持ETC1脂倦,但是iOS不支持。
ETC1/ETC1+A紋理的長寬可以不相等元莫,但要求是2的冪次方赖阻。
3.2 ETC2
ETC2是ETC1的擴展,壓縮比率一樣踱蠢,但壓縮質(zhì)量更高火欧,而且支持透明通道,能完整存儲RGBA信息朽基。
ETC2需要OpenGL ES 3.0(對應(yīng)WebGL 2.0)環(huán)境布隔,目前還有不少低端Android手機不兼容,iOS方面從 iPhone5S 開始都支持OpenGL ES 3.0稼虎。
ETC2和ETC1一樣,長寬可以不相等招刨,但要求是2的冪次方霎俩。
3.3 PVRTC
Creator中常用的是PVRTC4+A,壓縮比和ETC一樣沉眶,iOS全系列支持打却,但是Android不支持。另外PVR要求紋理長寬相等(正方形)且是2的冪次方谎倔,例如1280*720
的PNG圖片柳击,轉(zhuǎn)換后變成2048*2048
,這一點會大大增加內(nèi)存消耗片习。在實測中還發(fā)現(xiàn)轉(zhuǎn)換后的圖片質(zhì)量不如ETC1捌肴,存在模糊、毛邊現(xiàn)象藕咏,對畫面要求高的游戲不適合状知。
4 壓縮紋理的使用
壓縮紋理的使用非常簡單,根據(jù)構(gòu)建平臺添加需要的格式即可孽查,具體參見Creator官方文檔饥悴,本文不再重復(fù)了。
Creator編輯器還提供了轉(zhuǎn)換壓縮紋理的選項盲再,根據(jù)轉(zhuǎn)換速度分為Fast西设、Slow等好幾檔,速度越慢則畫面質(zhì)量越好答朋。但不管選哪個贷揽,只影響顯示效果和轉(zhuǎn)換時長,顯存占用都是一樣的绿映。一般情況下擒滑,顯存占用就是壓縮紋理的文件大小腐晾,例如文件大小是1.5M,則它占用的顯存也是1.5M丐一。
在設(shè)置壓縮紋理格式時藻糖,目前Creator 2.x版本還需手動一個一個設(shè)置。如果想一次性設(shè)置所有或部分資源库车,自己寫個腳本遍歷修改對應(yīng)的.meta
文件也比較方便巨柒,這里是一個我寫好的腳本 一鍵自動化設(shè)置壓縮紋理格式
5 總結(jié)
在實際項目中的測試結(jié)果是,單圖柠衍、自動圖集洋满、TexturePack合圖加起來超過兩千張圖片的Creator工程,使用PNG時打出來的apk包大小近500M珍坊,內(nèi)存占用1.3G牺勾。采用壓縮紋理后,包體大小降到150M阵漏,內(nèi)存占用降到600M驻民。
- 壓縮紋理的初始文件大小比PNG大1-2倍,但經(jīng)過zip或打包成apk履怯、ipa后回还,大小比PNG小了1/2-1/3,對減小包體有巨大好處叹洲。
- 從OpenGL ES 2.0開始柠硕,GPU紋理支持非2冪次方(例如,小于2048的圖片比2048圖片更節(jié)省內(nèi)存)运提,目前所有手機都已經(jīng)是OpenGL ES 2.0及以上了蝗柔。
- 對于Android原生平臺,要想兼容盡可能多的設(shè)備糙捺,又想發(fā)揮內(nèi)存和包體優(yōu)勢诫咱,目前最佳選擇是ETC1。
- 對于iOS原生平臺洪灯,PVR畫面質(zhì)量不佳坎缭,如果只考慮 iPhone5S 及以上設(shè)備,則使用ETC2比PVR好签钩。
- 采用壓縮紋理后掏呼,Creator的動態(tài)合圖會失效,因為動態(tài)合圖依賴于內(nèi)存中的紋理緩存铅檩,而壓縮紋理直接傳送到GPU憎夷。
- 壓縮紋理在壓縮時速度較慢,如果是第一次壓縮昧旨,整個過程可能在數(shù)個小時以上拾给,具體取決于資源數(shù)量祥得。
- OpenGL ES 3.0開始新推出一種ASTC格式,Android和iOS都支持蒋得,畫面質(zhì)量比PVR好级及,且不要求紋理長寬相等和2的冪次方。ASTC可能會是未來的統(tǒng)一格式额衙,但目前很多Android低端設(shè)備還不支持饮焦。