本來以為,etc1作為android 裝置的opengl標準,開源且最常用的的一種壓縮紋理格式,總會有人去翻譯一下khronos的文件,讀一下**,給大家作個普及的,不料就是搜不到。沒辦法,儘管英文不好,還是硬啃了下文件,把 etc1壓縮紋理的實現原理弄清楚了。
至於什麼是壓縮紋理,如何使用,可以參考:
檔案頭大小為16:
#define etc_pkm_header_size 16
將etc1紋理存成pkm檔案時,加上這個檔案頭,便於讀取時獲知大小、格式,上傳壓縮紋理時把這個頭去掉。
檔案頭內容為:特徵符——編碼寬——編碼高——實際寬——實際高
static
const
char kmagic = ;
static
const etc1_uint32 etc1_pkm_format_offset = 6;
static
const etc1_uint32 etc1_pkm_encoded_width_offset = 8;
static
const etc1_uint32 etc1_pkm_encoded_height_offset = 10;
static
const etc1_uint32 etc1_pkm_width_offset = 12;
static
const etc1_uint32 etc1_pkm_height_offset = 14;
儘管etc1是固定的壓縮比,但考慮到畫素不對齊的情況,實際寬和實際高還是有必要儲存的。
jpeg壓縮標準是把影象劃分為一系列8x8的畫素塊,然後每個畫素塊壓縮成變長編碼的。etc1則是4x4的畫素塊壓縮成固定的64位編碼(8位元組),由於固定,才有利於gpu內部實現並行解壓縮。
#define etc1_encoded_block_size 8
#define etc1_decoded_block_size 48 // rgb 三分量 * 4 * 4
因此,不考慮畫素非4對齊的情況,它的壓縮比是固定的48/8=6,至於常用的把argb分別儲存為兩張etc1紋理的做法,壓縮比是64/16=4。
畫素不對齊的情況如何處理,就自己想想吧,反正不是大問題。
4x4的畫素點與64位編碼對應關係如下:
1、將 4x4 的畫素點劃分為兩個subblock,橫分或者豎分【1個位表示:flipbit】。
2、兩部分的畫素rgb求均值,總共用24個位表示兩個rgb均值,分兩種方案【1個位表示:diffbit】
(1)兩個subblock的rgb均值都用4位表示。剛好4*3*2=24位。
(2)兩個subblock的rgb值相差在 [-4,3]區間(5位表示的情況下,對應常規的8位表示是[-32,24]),第乙個subblock的rgb值用5位表示,第二個用3位差值表示。
3、解碼時,畫素值由rgb均值加上差值而得,差值表為8x4大小。每乙個subblock使用的是其中一行【行號需要3個位,兩個subblock,加起來6個位】,每個畫素點對應所取差值行中乙個數【編號需要2個位,這樣就16x2=32個位】。ps:rgb三個分量是用同乙個差值。
64位的編碼分成兩部分,高位和低位。
低位儲存每個畫素點的差值行序號,按大端儲存方式,分兩部分,前一部分儲存高位,後一部分儲存低位。
高位儲存rgb均值,subblock所用的差值表行號,再加上 flipbit 和 diffbit
詳細內容直接上文件上的圖:
橫分/豎分示例圖,圖中每個字母**乙個畫素:
etc1的編碼流程如下:
1、將影象劃分為一系列 4x4 的子塊。
2、對每個子塊,嘗試所有的編碼可能性,取解碼後和原block畫素差值和最小的一種編碼。
(1)是否flip,這個決定subblock如何劃分
(2)每個subblock用哪一行差值表
(3)每個畫素取哪一列的差值
注:決定好flip之後,顏色均值和是否能用diff方式已經確定,這個不用遍歷。
3、合併所有子塊編碼。
不難看出,編碼過程需要遍歷所有可能性,其複雜度遠大於解碼,每乙個 rgb 畫素變成了乙個精度較低的rgb均值和乙個2位差值號,因此產生壓縮。這種**式表述自然本身就存在偏差,壓縮損失亦來自於此。
安卓中壓縮紋理ETC1和ETC2
etc是紋理壓縮演算法,pkm是紋理打包格式。pkm裡面放的是往往是etc壓縮的紋理。1.標頭檔案 1 etc1的檔案頭大小為16 2 將etc1紋理存成pkm檔案時,加上這個檔案頭,便於讀取時獲知大小 格式,上傳壓縮紋理時把這個頭去掉。3 檔案頭內容為 特徵符 編碼寬 編碼高 實際寬 實際高 4 ...
載入ETC1格式編碼的PVR壓縮檔案
1.通過pvrtextool將需要壓縮的轉換為etc1格式編碼的pvr檔案 2.解析pvr檔案,官網有pvr檔案的說明文件,pvr檔案由header format metadata format texture data三部分組成。如果是v3版本,可這樣定義pvr檔案頭部格式,記得指定位元組對齊的方...
移動端紋理壓縮格式
裝置資源的限制和製作過程中對表現的無限追求永遠是矛盾點,不會隨裝置的發展而轉移。紋理壓縮就是這種矛盾的一種解決方式,不同於png jgp這種硬碟壓縮方式而言,dxt,etc等紋理壓縮方式可以在遊戲執行中無需cpu解壓就被gpu直接取樣,可以極大的減少記憶體和頻寬的占用,提公升執行效率,對移動遊戲而言...