一、ASTC紋理壓縮格式介紹
ASTC是在OpenGL ES3.0出現后在2012年中產生的一種業界領先的紋理壓縮格式,它的壓縮分塊從4x4到12x12最終可以壓縮到每個像素占用1bit以下,壓縮比例有多種可選。ASTC格式支持RGBA,且適用於2的冪次方長寬等比尺寸和無尺寸要求的NPOT(非2的冪次方)紋理。
以ASTC 4x4 block壓縮格式為例,每個像素占用1字節,8bits。一張1024*1024大小的貼圖壓縮后的大小為1M。
ASTC在壓縮質量和容量上有很大的優勢。
文檔中有詳細的測試數據:
Using ASTC Texture Compression for Game Assets
二、適配機型
1、iOS
蘋果從A8處理器開始支持 ASTC,iPhone6及iPad mini 4以上iOS設備支持,2014年的iPhone 5s及iPad mini 3以前的設備不支持。
2、安卓
安卓主流壓縮格式正在從ETC2轉向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的不確定性,我們對一些當前用戶占比較高的低配機型進行了ASTC格式兼容性測試,並補充了一些占比低的GPU型號Mali-G71、Adreno 306、Adreno 308、Adreno 405做測試(測試時間2020.5.21):
市面上大部分機型都支持OpenGL ES 3.1以上,少數GPU配置較低的機型支持OpenGL ES 3.0但不支持ASTC壓縮格式,在2020年4月統計的市面占比不到1.5%,從個人角度看ASTC壓縮格式是可以普及使用的。
補充: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(在本文中翻譯為像素占用),為了更直觀的感受,使用一張容易產生壓縮失真的貼圖進行示例。
1、ASTC與ETC2格式的壓縮結果與容量對比
RGB8 vs ETC2 4bits vs ASTC 6x6
從上圖可以看出,一張512x512尺寸的貼圖(不帶Alpha通道,開啟Mipmap)的容量為1MB,壓縮為ETC2 4 bits后容量為170.7KB,有明顯失真,壓縮為ASTC 6x6后容量為154.7KB,無明顯失真,ASTC 6x6的容量小於ETC2 4 bits,壓縮質量高於ETC2 4 bits。
ASTC 6x6 vs ETC2 4bits vs ASTC 8x8
從上圖可以看出,壓縮為ASTC 8x8后容量為85.4KB,容量約為ETC2 4 bits的50%,壓縮質量高於ETC2 4 bits。
2、無Alpha通道,RGB 24 位/像素的壓縮比率選擇
ASTC 6x6 vs ASTC 8x8 vs ASTC 10x10
從上圖可以看出,一張512x512尺寸的貼圖(不帶Alpha通道),壓縮為ASTC 6x6、ASTC 8x8、ASTC10x10后均無明顯失真,壓縮為ASTC 8x8后容量與ASTC 6x6相比減小了約44.8%,壓縮為ASTC10x10后容量與ASTC 8x8相比減小了約33.7%。
以法線貼圖舉例:
RGB8 vs ASTC 4x4 vs ASTC 5x5 vs ASTC 6x6
從上圖可以看出,一張512x512尺寸的法線貼圖,壓縮為ASTC 4x4無明顯失真,壓縮為ASTC 5x5肉眼可見失真,壓縮為ASTC6x6后明顯失真。
以面部貼圖舉例:
從上圖可以看出,壓縮為ASTC 6x6無明顯失真,壓縮為ASTC 8x8后肉眼可見失真。
結論:無Alpha通道的貼圖建議壓縮格式為ASTC 8x8。如果貼圖為法線貼圖,建議壓縮格式為ASTC 5x5。有更高要求的貼圖(比如面部、場景地面),可以設置壓縮格式為ASTC 6x6,法線貼圖為ASTC 4x4。
結論與NV文檔數據對比:
唯一有出入的地方是普通貼圖的壓縮選擇ASTC 6x6還是ASTC 8x8,從個人角度,8x8的推薦指數應該為0。
3、帶Alpha通道,RGBA 32 位/像素的壓縮比率選擇
ASTC 4x4 vs ASTC 5x5 vs ASTC 6x6
從上圖可以看出,壓縮為ASTC 5x5肉眼可見失真,壓縮為ASTC 6x6后有明顯失真,壓縮為ASTC 5x5后容量與ASTC 4x4相比減小了約34.9%。在同一壓縮格式下,帶Alpha通道比不帶Alpha通道的壓縮質量下降明顯。
結論:有Alpha通道的貼圖建議壓縮格式為ASTC 5x5。有更高要求的貼圖(比如特效、UI),可以設置壓縮格式為ASTC 4x4。
結論與NV文檔數據對比一致:
4、有無Alpha通道對壓縮的影響
在同一壓縮格式下,貼圖容量不變,有無Alpha通道對壓縮結果有很大影響,帶Alpha通道的貼圖壓縮質量下降。
從上圖可以看出,對於帶Alpha通道的32位圖和不帶Alpha通道的24位圖,選擇同一壓縮格式時,壓縮結果有很大差異。
對於一張帶Alpha通道的32位圖,選擇Import Settings中的Alpha Source為None,壓縮結果與不帶Alpha通道一致。
5、其他問題
1)對Shader帶來的影響
默認貼圖是"black"時,如果貼圖缺省,默認值是(0,0,0,0),A通道讀取出來是0,使用RGB ETC2 4bits格式時,A通道讀取出來是0,使用ASTC格式時,A通道讀取出來是1。這里要注意Shader默認值的考慮。
2)JPEG格式已經是有損格式,在JPEG丟失的精度與ASTC壓縮無關。
3)關於貼圖尺寸。
壓縮格式支持非2的冪次方時,只要硬件支持該壓縮格式,就可以使用NPOT紋理。但是,2的冪次方紋理比其他尺寸更優,這里有復雜的圖形學因素。
參考文章:https://www.zhihu.com/question/376921536/answer/1063272336
簡單的理解,貼圖在GPU中是以塊為單位存儲的,為了盡可能節省內存和帶寬,壓縮格式對貼圖也是分塊存儲的。在遞歸或循環時,如果一個數是2的冪次方,可以被2整除,而且商也是2的冪次方。OpenGL API支持非2的冪次方,是因為考慮到易用性隱藏了細節,在內部處理了一些必要的拉伸或填充操作。所以,在無特殊要求時,盡量使用POT紋理,並且制作時盡量按照實際應用尺寸來制作,避免一些高精度壓縮到低精度使用的情況。
4)無論貼圖本身是否帶Alpha信息,ASTC壓縮的不同設置直接決定壓縮大小。控制貼圖資源的包體大小,依賴於ASTC壓縮格式的規范是否合理,畢竟壓縮為ASTC 8x8后容量與ASTC 6x6相比減小了約44.8%(85.4KB vs 154.7KB),壓縮為ASTC 8x8后容量與ASTC 4x4相比減小了約300%(85.4KB vs 341.4KB)。而我們通常檢查Alpha通道是否為空,可以幫助我們判斷Alpha的信息是否冗余,是否應該設置更低的壓縮精度。
5)ASTC壓縮的算法比較智能,它會為變化更大的通道RGB或者A分配更高的權重,而且對於單色圖,RGB通道內容一樣時,使用較低的像素占用就可以達到很好的效果。對於單色圖完全沒有必要使用R8壓縮格式,而是應該將RGB通道填充一樣的信息,選擇ASTC較低的像素占比,如ASTC8x8。
6)在項目實際使用中發現,對於法線貼圖,ETC2 4bits的壓縮效果比ASTC 5x5好,對於帶透明通道的貼圖,存在ETC2 8 Bits比ASTC 4x4更優的情況,之前在測試中漏掉了對比,還需要進一步對比,根據實際情況進行選擇。