ASTC紋理壓縮
一、ASTC紋理壓縮格式介紹
ASTC是在OpenGL ES3.0出現(xiàn)后在2012年中產(chǎn)生的一種業(yè)界領(lǐng)先的紋理壓縮格式,它的壓縮分塊從4x4到12x12最終可以壓縮到每個像素占用1bit以下,壓縮比例有多種可選。ASTC格式支持RGBA,且適用于2的冪次方長寬等比尺寸和無尺寸要求的NPOT(非2的冪次方)紋理。

以ASTC 4x4 block壓縮格式為例,每個像素占用1字節(jié),8bits。一張1024*1024大小的貼圖壓縮后的大小為1M。
ASTC在壓縮質(zhì)量和容量上有很大的優(yōu)勢。
文檔中有詳細(xì)的測試數(shù)據(jù):
http://developer.nvidia.com/astc-texture-compression-for-game-assets
二、適配機(jī)型
1、iOS
蘋果從A8處理器開始支持 ASTC,iPhone6及iPad mini 4以上iOS設(shè)備支持,2014年的iPhone 5s及iPad mini 3以前的設(shè)備不支持。
2、安卓
安卓主流壓縮格式正在從ETC2轉(zhuǎn)向ASTC。
Unity官方對安卓ASTC格式支持的說明:
https://docs.unity3d.com/Manual/class-TextureImporterOverride.html

官方文檔中提到GPU對ASTC的支持情況:所有支持OpenGL ES 3.1和部分支持OpenGL ES 3.0的GPU。
鑒于OpenGL ES 3.0 GPU的不確定性,我們對一些當(dāng)前用戶占比較高的低配機(jī)型進(jìn)行了ASTC格式兼容性測試,并補(bǔ)充了一些占比低的GPU型號Mali-G71、Adreno 306、Adreno 308、Adreno 405做測試(測試時間2020.5.21):

市面上大部分機(jī)型都支持OpenGL ES 3.1以上,少數(shù)GPU配置較低的機(jī)型支持OpenGL ES 3.0但不支持ASTC壓縮格式,在2020年4月統(tǒng)計(jì)的市面占比不到1.5%,從個人角度看ASTC壓縮格式是可以普及使用的。
補(bǔ)充:Unity官方文檔2018.4版本中有介紹對ASTC壓縮格式的支持:https://docs.unity3d.com/2018.4/Documentation/Manual/class-TextureImporterOverride.html
Texture Compression ASTC Platform Support:tvOS (all), iOS (A8), Android (PowerVR 6XT, Mali T600 series, Adreno 400 series, Tegra K1)
三、壓縮比率的選擇
前文我們了解了不同的ASTC格式的Bits Per Pixel(在本文中翻譯為像素占用),為了更直觀的感受,使用一張容易產(chǎn)生壓縮失真的貼圖進(jìn)行示例。
1、ASTC與ETC2格式的壓縮結(jié)果與容量對比

從上圖可以看出,一張512x512尺寸的貼圖(不帶Alpha通道,開啟Mipmap)的容量為1MB,壓縮為ETC2 4 bits后容量為170.7KB,有明顯失真,壓縮為ASTC 6x6后容量為154.7KB,無明顯失真,ASTC 6x6的容量小于ETC2 4 bits,壓縮質(zhì)量高于ETC2 4 bits。

從上圖可以看出,壓縮為ASTC 8x8后容量為85.4KB,容量約為ETC2 4 bits的50%,壓縮質(zhì)量高于ETC2 4 bits。
2、無Alpha通道,RGB 24 位/像素的壓縮比率選擇

從上圖可以看出,一張512x512尺寸的貼圖(不帶Alpha通道),壓縮為ASTC 6x6、ASTC 8x8、ASTC10x10后均無明顯失真,壓縮為ASTC 8x8后容量與ASTC 6x6相比減小了約44.8%,壓縮為ASTC10x10后容量與ASTC 8x8相比減小了約33.7%。
以法線貼圖舉例:

從上圖可以看出,一張512x512尺寸的法線貼圖,壓縮為ASTC 4x4無明顯失真,壓縮為ASTC 5x5肉眼可見失真,壓縮為ASTC6x6后明顯失真。

以面部貼圖舉例:

從上圖可以看出,壓縮為ASTC 6x6無明顯失真,壓縮為ASTC 8x8后肉眼可見失真。
結(jié)論:無Alpha通道的貼圖建議壓縮格式為ASTC 8x8。如果貼圖為法線貼圖,建議壓縮格式為ASTC 5x5。有更高要求的貼圖(比如面部、場景地面),可以設(shè)置壓縮格式為ASTC 6x6,法線貼圖為ASTC 4x4。
結(jié)論與NV文檔數(shù)據(jù)對比:

唯一有出入的地方是普通貼圖的壓縮選擇ASTC 6x6還是ASTC 8x8,從個人角度,8x8的推薦指數(shù)應(yīng)該為0。
3、帶Alpha通道,RGBA 32 位/像素的壓縮比率選擇

從上圖可以看出,壓縮為ASTC 5x5肉眼可見失真,壓縮為ASTC 6x6后有明顯失真,壓縮為ASTC 5x5后容量與ASTC 4x4相比減小了約34.9%。在同一壓縮格式下,帶Alpha通道比不帶Alpha通道的壓縮質(zhì)量下降明顯。
結(jié)論:有Alpha通道的貼圖建議壓縮格式為ASTC 5x5。有更高要求的貼圖(比如特效、UI),可以設(shè)置壓縮格式為ASTC 4x4。
結(jié)論與NV文檔數(shù)據(jù)對比一致:

4、有無Alpha通道對壓縮的影響
在同一壓縮格式下,貼圖容量不變,有無Alpha通道對壓縮結(jié)果有很大影響,帶Alpha通道的貼圖壓縮質(zhì)量下降。

從上圖可以看出,對于帶Alpha通道的32位圖和不帶Alpha通道的24位圖,選擇同一壓縮格式時,壓縮結(jié)果有很大差異。
5、其他問題
1)對Shader帶來的影響
默認(rèn)貼圖是"black"時,如果貼圖缺省,默認(rèn)值是(0,0,0,0),A通道讀取出來是0,使用RGB ETC2 4bits格式時,A通道讀取出來是0,使用ASTC格式時,A通道讀取出來是1。這里要注意Shader默認(rèn)值的考慮。
2)JPEG格式已經(jīng)是有損格式,在JPEG丟失的精度與ASTC壓縮無關(guān)。
3)關(guān)于貼圖尺寸。
壓縮格式支持非2的冪次方時,只要硬件支持該壓縮格式,就可以使用NPOT紋理。但是,2的冪次方紋理比其他尺寸更優(yōu),這里有復(fù)雜的圖形學(xué)因素。
參考文章:https://www.zhihu.com/question/376921536/answer/1063272336
簡單的理解,貼圖在GPU中是以塊為單位存儲的,為了盡可能節(jié)省內(nèi)存和帶寬,壓縮格式對貼圖也是分塊存儲的。在遞歸或循環(huán)時,如果一個數(shù)是2的冪次方,可以被2整除,而且商也是2的冪次方。OpenGL API支持非2的冪次方,是因?yàn)榭紤]到易用性隱藏了細(xì)節(jié),在內(nèi)部處理了一些必要的拉伸或填充操作。所以,在無特殊要求時,盡量使用POT紋理,并且制作時盡量按照實(shí)際應(yīng)用尺寸來制作,避免一些高精度壓縮到低精度使用的情況。
4)無論貼圖本身是否帶Alpha信息,ASTC壓縮的不同設(shè)置直接決定壓縮大小??刂瀑N圖資源的包體大小,依賴于ASTC壓縮格式的規(guī)范是否合理,畢竟壓縮為ASTC 8x8后容量與ASTC 6x6相比減小了約44.8%(85.4KB vs 154.7KB),壓縮為ASTC 8x8后容量與ASTC 4x4相比減小了約300%(85.4KB vs 341.4KB)。而我們通常檢查Alpha通道是否為空,可以幫助我們判斷Alpha的信息是否冗余,是否應(yīng)該設(shè)置更低的壓縮精度。
5)ASTC壓縮的算法比較智能,它會為變化更大的通道RGB或者A分配更高的權(quán)重,而且對于單色圖,RGB通道內(nèi)容一樣時,使用較低的像素占用就可以達(dá)到很好的效果。對于單色圖完全沒有必要使用R8壓縮格式,而是應(yīng)該將RGB通道填充一樣的信息,選擇ASTC較低的像素占比,如ASTC8x8。
6)在項(xiàng)目實(shí)際使用中發(fā)現(xiàn),對于法線貼圖,ETC2 4bits的壓縮效果比ASTC 5x5好,對于帶透明通道的貼圖,存在ETC2 8 Bits比ASTC 4x4更優(yōu)的情況,之前在測試中漏掉了對比,還需要進(jìn)一步對比,根據(jù)實(shí)際情況進(jìn)行選擇。