參考
為什么需要紋理壓縮
移動(dòng)端紋理壓縮格式
干貨:Unity游戲開(kāi)發(fā)圖片紋理壓縮方案
Creator使用壓縮紋理
常用紋理和紋理壓縮格式
移動(dòng)設(shè)備的紋理壓縮方案
各種移動(dòng)GPU壓縮紋理的使用方法
一、DXT PVR ETC
在軟件開(kāi)發(fā),特別是三維應(yīng)用中,紋理隨處可見(jiàn),但受限于網(wǎng)絡(luò)環(huán)境和硬件能力,紋理也是一大瓶頸。而且在一般的三維應(yīng)用中,紋理所占大小基本都會(huì)在1/2以上,模型中往往超過(guò)2/3?;蛟S你會(huì)說(shuō),紋理不就是一張圖嗎,有那么重要嗎?如下兩張對(duì)比圖,可能你會(huì)認(rèn)為前者逼格高,但對(duì)于正常人而言,后者顯然要好很多。正是有了紋理,如同在骨架上賦予了皮膚,讓我們的應(yīng)用更加的逼真,貼近現(xiàn)實(shí)。

而你能想象到嗎?如上的模型一共有三張紋理,其中之一效果如下:

看上去怪怪的。其實(shí)在紋理的壓縮中,人們先想到了如何去除冗余信息,對(duì)稱的部分只保留一份,盡可能讓不同的部分緊湊,充分利用好每一個(gè)像素來(lái)保存有效數(shù)據(jù)。得益于對(duì)稱在大自然中的普遍性,這種方式確實(shí)極大的減少了紋理像素。
紋理的拼接是紋理壓縮的開(kāi)始,采用不同的壓縮方式對(duì)紋理最終的大小影響也是顯著的。比如上面的這張紋理在不同壓縮格式下的大小差別也是非常顯著的(原始文件為tga格式,通過(guò)Photoshop轉(zhuǎn)換為其他格式,默認(rèn)選項(xiàng)):

(注:原作者在評(píng)論中承認(rèn)筆誤,jpg實(shí)際上是有損壓縮)如果按照上面表格的邏輯,用jpg或png格式就好了,無(wú)損壓縮,而且也是最小的。確實(shí)在很多情況下這是一個(gè)比較好的選擇,比如網(wǎng)絡(luò)帶寬有限,這樣可以很好的節(jié)約帶寬和下載時(shí)間,而B(niǎo)mp,tga,png以及jpg都是無(wú)損格式。但這類(lèi)壓縮存在一個(gè)致命缺陷,他們都是基于整幅圖片下進(jìn)行的壓縮,比如霍夫曼編碼等,這樣像素和像素之間在解碼的過(guò)程中存在依賴關(guān)系,無(wú)法直接實(shí)現(xiàn)單個(gè)像素級(jí)別的解析,這就發(fā)揮不了顯卡的并發(fā)能力,更重要的是問(wèn)題在于無(wú)論是png還是jpeg最終在顯存中解碼后都是RGBA的紋理格式,因此并無(wú)法減少顯存的占用率。比如一張256256的RGBA紋理,無(wú)論是png還是jpg格式,雖然文件大小不一樣,在顯卡中的大小仍然是256256*4的顯存空間。
不同于png、jgp這種硬盤(pán)壓縮方式而言,DXT,ETC等紋理壓縮方式可以在游戲運(yùn)行中無(wú)需CPU解壓就被GPU直接采樣,可以極大的減少內(nèi)存和帶寬的占用,提升運(yùn)行效率,對(duì)移動(dòng)游戲而言更是如此。
1.DXT
DXT是一種有損紋理壓縮算法,微軟的Direct中支持,DXT的格式包括DXT1~DXT5,其中DXT1和DXT5較為多見(jiàn),后面會(huì)做詳細(xì)討論??梢哉f(shuō)DXT是目前應(yīng)用最廣泛的紋理壓縮格式,可以認(rèn)為所有的PC端顯卡都支持DXT壓縮,維基百科記錄,該專利有效期到2017年10月2號(hào)。

DXT算法非常容易理解,而且整體看上去效果不錯(cuò),但如果對(duì)局部特寫(xiě),會(huì)發(fā)現(xiàn)在細(xì)節(jié)上會(huì)有很多丟失,這也是算法本身導(dǎo)致的,畢竟每個(gè)塊只有兩個(gè)顏色,而其他顏色都是在這兩個(gè)顏色區(qū)間的差值,如果當(dāng)前區(qū)域內(nèi)還有其他顯著顏色則必然會(huì)有丟失。

這種信息的丟失主要集中在比較細(xì)的邊界中,但DXT1在壓縮率上是RGB的6倍,這種問(wèn)題可以通過(guò)提高紋理分辨率的方式來(lái)解決,高寬放大41%(1.41*1.41=1.9881),這樣整個(gè)紋理是以前的2倍,但壓縮率還能保持為3倍,也是可以接受的。在DXT中還有一個(gè)主要的損失,就是RGB的24位轉(zhuǎn)為了16位顏色,16位中R&B各占5位,但是G占了6位,這是因?yàn)槿搜蹖?duì)綠色最為敏感。

另外一個(gè)問(wèn)題就是DXT3和DXT5之間的對(duì)比,相比DXT1不支持透明度(但支持是否透明),DXT5要大一倍(多了64bit),和之前顏色保存方案一樣對(duì)透明度也保存了兩個(gè)16位的顏色和對(duì)應(yīng)的調(diào)色板,對(duì)RGBA的效果也得到了保證,但DXT3思路不一樣,它是對(duì)每一個(gè)像素保存了4bit的透明度,同樣也是多了64bit,但此時(shí)畢竟只有16個(gè)透明度選項(xiàng),相比DXT5,在壓縮率上相當(dāng),但對(duì)透明色的處理不夠細(xì)膩,因此在實(shí)用性上并不推薦DXT3。
盡管DXT在細(xì)節(jié)上有明顯硬傷,在總體效果不錯(cuò),而且確實(shí)是一種強(qiáng)大的壓縮方式,所以在多數(shù)紋理壓縮選擇中都是最佳方案,幾乎可以認(rèn)為是PC下的標(biāo)準(zhǔn)壓縮格式。
2.PVR&ETC
也許是出于專利和商業(yè)角度,也許確實(shí)DXT在移動(dòng)端確實(shí)無(wú)法滿足要求,DXT并沒(méi)有在移動(dòng)端得到很大的支持,相反,在iOS設(shè)備中支持的是PVR壓縮,在Android中支持的是ETC壓縮。
DXT在細(xì)節(jié)上缺陷明顯,最重要的原因是當(dāng)把紋理分為4*4像素的區(qū)域塊后,每個(gè)塊之間都是獨(dú)立的,盡管這極大的簡(jiǎn)化了壓縮算法,但卻丟失了相鄰塊之間這種普遍的相似性。這是算法本身導(dǎo)致的,而PVR則會(huì)考慮該區(qū)域塊對(duì)應(yīng)的右側(cè),下側(cè)和右下側(cè)的三個(gè)區(qū)域塊的關(guān)聯(lián)性。
從現(xiàn)實(shí)的角度來(lái)看,受制于專利和硬件廠商,我們并沒(méi)太多選擇的余地,Android下就要用ETC,iOS下只能PVR,而在PC上不用DXT估計(jì)就要被嘲諷了。但這也是一個(gè)很棘手的問(wèn)題,比如在WebGL下,特別是Android下差異化很大,是否支持紋理壓縮,甚至在同一個(gè)設(shè)備不同的瀏覽器,因?yàn)轵?qū)動(dòng)的不一致,可能系統(tǒng)自帶的會(huì)支持ETC壓縮,而微信等QQ瀏覽器下并不支持。而且華為的手機(jī)貌似在瀏覽器級(jí)別下都不支持ETC(硬件支持,還是驅(qū)動(dòng)的問(wèn)題)。而如果在移動(dòng)設(shè)備上不用壓縮,顯存是有限的,除非你在數(shù)據(jù)量上做出犧牲,怎么解決都很矛盾,相比而言,iOS下則要舒服很多。
| 格式 | 壓縮比 | GPU支持 | 描述 | 圖片要求 |
|---|---|---|---|---|
| DXT | DXT1:0.3/DXT5:0.6 | Windows\Android(Nvidia Tegra and Intel Bay Trail) | 分為DXT1-DXT5這五個(gè)級(jí)別,DXT1 適用于不具有透明度或者僅具有一位Alpha的貼圖,DXT3和DX5支持包含4位alpha通道的RGB紋理 | 無(wú) |
| ATC RGBA/RGB | RGBA:0.25/RGB:0.125 | Qualcomm -Adreno | 高通GPU支持格式,支持帶有Alpha的RGB紋理壓縮。 | 無(wú) |
| PVRTC RGBA/RGB | 2bit:0.125/4bit:0.25 | PowerVR | IOS平臺(tái)都支持,支持每個(gè)像素2位或者4位的紋理,包含或者不包含alpha通道都可以;PVRTC 2-bpp把一個(gè)8×4的像素單元組壓成一個(gè)64位的數(shù)據(jù)塊,壓縮效果比較差;PVRTC 4-bpp把一個(gè)4×4的像素單元組壓成一個(gè)64位的數(shù)據(jù)塊。游戲中使用4位壓縮更多。 | 尺寸為2的N次冪,并且寬高相同。 |
| ETC1 RGB 4Bit | 0.125 | 支持Opnegl ES2.0的GPU | OpenGL ES2.0版本支持,移動(dòng)GPU均支持的一個(gè)格式,遺憾的是不支持Alpha通道。ETC1把一個(gè)4x4的像素單元組壓成一個(gè)64位的數(shù)據(jù)塊。游戲開(kāi)發(fā)中采用最多的格式,不過(guò)麻煩的是需要對(duì)Alpha通道進(jìn)行單獨(dú)存儲(chǔ),Unity5.4.3版本之后提供了官方支持 | 尺寸為2的N次冪,長(zhǎng)寬可不同 |
| ETC2 ARGB/RGB 4bit | RGBA:0.25/RGB:0.125 | 支持Opnegl ES3.0的GPU | OpenGL ES 3.0以上才支持,補(bǔ)全了ETC1不支持Alpha通道,支持更高質(zhì)量的壓縮。雖然如此,從Android官方數(shù)據(jù)來(lái)看,還有相當(dāng)大的設(shè)備是采用Opengl ES2.0;使用需要謹(jǐn)慎,不過(guò)隨著設(shè)備更新?lián)Q代,開(kāi)發(fā)時(shí)間周期比較長(zhǎng)的游戲可以考慮直接使用 | 尺寸為4的倍數(shù) |
Unity官網(wǎng)對(duì)每個(gè)平臺(tái)默認(rèn)的紋理壓縮格式以及使用建議給出了詳細(xì)描述,需要注意的是:在不同移動(dòng)GPU平臺(tái)下選擇GPU支持的壓縮紋理,就可以在不需要CPU解壓的情況下直接被GPU采樣,節(jié)省CPU內(nèi)存和帶寬,也可以節(jié)省存儲(chǔ)的體積。如果目標(biāo)平臺(tái)不支持設(shè)置的壓縮格式,紋理將解壓為RGBA32或者RGB24,浪費(fèi)CPU時(shí)間和內(nèi)存。
二、ASTC
參考幾種主流貼圖壓縮算法的實(shí)現(xiàn)原理
從IOS9(A8架構(gòu))Apple 手機(jī)開(kāi)始支持ASTC壓縮格式 ,如果考慮放棄Apple 6代之前的手機(jī)兼容問(wèn)題了,可以直接使用了。相對(duì)于PVRTC2/4而言,ASTC(4X4)的壓縮比會(huì)增加到0.25,不過(guò)顯示效果也會(huì)好很多,而且不需要把圖片設(shè)置為方形。
Using ASTC Texture Compression for Game Assets 說(shuō)明的比較詳細(xì),也給出了一些使用上的建議,即針對(duì)不同貼圖類(lèi)型給出不同的壓縮方案。
三、laya egret支持情況
1.laya問(wèn)答 H5游戲能使用壓縮紋理(ETC,PVR等)嗎?
Q:H5游戲能使用壓縮紋理(ETC,PVR等)嗎?
A:部分瀏覽器會(huì)不支持(比如safari)
Q:那laya里面能根據(jù)不同瀏覽器(或不同平臺(tái))使用不同壓縮格式的紋理嗎?
A:你自己是可以獲取到當(dāng)前是哪個(gè)瀏覽器的,自行處理即可
2.LAYA Runtme目前支持 ETC/DXT或者PVR這類(lèi)格式嗎?在文檔中沒(méi)有找到這類(lèi)的說(shuō)明
LayaAir目前暫時(shí)還不支持ETC/DXT/PVR這類(lèi)格式!關(guān)注layaAir的版本引擎更新日志即可,支持了我們會(huì)及時(shí)告知!
3.Egret 內(nèi)存分析-RES加載資源后存在雙份內(nèi)存無(wú)法釋放的問(wèn)題
支持pvr、etc已經(jīng)在計(jì)劃中。