個人理解的 紋理壓縮

2021-07-25 14:43:31 字數 3266 閱讀 4213



2. 壓縮紋理的必要性

1)首先要說一下影象檔案格式和紋理格式的區別。

常用的影象檔案格式有bmp,tga,jpg,gif,png等;

常用的紋理格式有r5g6b5,a4r4g4b4,a1r5g5b5,r8g8b8, a8r8g8b8等。

檔案格式是影象為了儲存資訊而使用的對資訊的特殊編碼方式,它儲存在磁碟中,或者記憶體中,但是並不能被gpu所識別,因為以向量計算見長的gpu對於這些 複雜的計算無能為力。這些檔案格式當被遊戲讀入後,還是需要經過cpu解壓成r5g6b5,a4r4g4b4,a1r5g5b5,r8g8b8, a8r8g8b8等畫素格式,再傳送到gpu端進行使用。

紋理格式是能被gpu所識別的畫素格式,能被快速定址並取樣。

舉個例子,dds檔案是遊戲開發中常用的檔案格式,它內部可以包含a4r4g4b4的紋理格式,也可以包含a8r8g8b8的紋理格式,甚至可以包含dxt1的紋理格式。在這裡dds檔案有點容器的意味。

opengl es 2.0支援以上提到的r5g6b5,a4r4g4b4,a1r5g5b5,r8g8b8,a8r8g8b8等紋理格式,其中 r5g6b5,a4r4g4b4,a1r5g5b5每個畫素占用2個位元組(byte),r8g8b8每個畫素占用3個位元組,a8r8g8b8每個畫素占用 4個位元組。

對於一張512*512的紋理的話,r5g6b5格式的檔案需要占用512kb(他所佔的記憶體就是512*512*2=512kb)的容量,a8r8g8b8格式的檔案需要占用1mb的容量;如果是 1024*1024的紋理,則各需要2m和4m的容量,這對於動輒需要幾

十、幾百張甚至更多紋理的遊戲,上g容量的遊戲在移動平台上是不容易被接受的(當然,還是有1、2g的大作的,裡面包含了幾千張的紋理)。(這裡的容量就是記憶體)

聰明的設計師們在想,有沒有其他辦法,既能表現豐富的色彩和細節,又能是最小失真的情況下,達到更小的紋理容量呢。壓縮紋理格式應運而生(當然,並不是在移動平台後才有的產物)。

3. 常見的壓縮紋理格式

基於opengl es的壓縮紋理有常見的如下幾種實現:

1)etc1(ericsson texture compression)

2)pvrtc (powervr texture compression)

3)atitc (ati texture compression)

4)s3tc (s3 texture compression)

etc1:

etc1格式是opengl es圖形標準的一部分,並且被所有的android裝置所支援。

擴充套件名為: gl_oes_compressed_etc1_rgb8_texture,不支援透明通道,所以僅能用於不透明紋理。

當載入壓縮紋理時,引數支援如下格式:

gl_etc1_rgb8_oes(rgb,每個畫素0.5個位元組)

pvrtc:

支援的gpu為imagination technologies的powervr sgx系列。

opengl es的擴充套件名為: gl_img_texture_compression_pvrtc。

當載入壓縮紋理時,引數支援如下幾種格式:

gl_compressed_rgb_pvrtc_4bppv1_img (rgb,每個畫素0.5個位元組)

gl_compressed_rgb_pvrtc_2bppv1_img (rgb,每個畫素0.25個位元組)

gl_compressed_rgba_pvrtc_4bppv1_img (rgba,每個畫素0.5個位元組)

gl_compressed_rgba_pvrtc_2bppv1_img (rgba,每個畫素0.25個位元組)

atitc:

支援的gpu為qualcomm的adreno系列。

支援的opengl es擴充套件名為: gl_ati_texture_compression_atitc。

當載入壓縮紋理時,引數支援如下型別的紋理:

gl_atc_rgb_amd (rgb,每個畫素0.5個位元組)

gl_atc_rgba_explicit_alpha_amd (rgba,每個畫素1個位元組)

gl_atc_rgba_interpolated_alpha_amd (rgba,每個畫素1個位元組)

s3tc

也被稱為dxtc,在pc上廣泛被使用,但是在移動裝置上還是屬於新鮮事物。支援的gpu為nvidia tegra系列。

opengl es擴充套件名為:

gl_ext_texture_compression_dxt1和gl_ext_texture_compression_s3tc。

當載入壓縮紋理時,的引數有如下幾種格式:

gl_compressed_rgb_s3tc_dxt1 (rgb,每個畫素0.5個位元組)

gl_compressed_rgba_s3tc_dxt1 (rgba,每個畫素0.5個位元組)

gl_compressed_rgba_s3tc_dxt3 (rgba,每個畫素1個位元組)

gl_compressed_rgba_s3tc_dxt5 (rgba,每個畫素1個位元組)

由此可見,mali系列gpu只支援etc1格式的壓縮紋理,而且該紋理不支援透明通道,有一定侷限性。

以上壓縮紋理格式每個畫素大小相對a8r8g8b8格式的比例,最高壓縮比是16:1,最低壓縮比是4:1,對於減小紋理的資料容量有明顯作用,相應在顯 存頻寬上也有明顯優勢,從而提高遊戲的執行效率(此特性沒有絕對數值,根據每個遊戲的用法和瓶頸點不同而有差別)。

個人理解:

1. bmp,tga,jpg,gif,png這些影象檔案,其實是被載入到遊戲中的時候,cpu重新解壓成r5g6b5,a4r4g4b4,a1r5g5b5,r8g8b8, a8r8g8b8等畫素格式,紋理的壓縮格式,並不是這些影象檔案有任何的關聯。

也就是說,假如一張rgba的512*512 的.png,看起來只有300kb,但是,載入到記憶體中,就有 512 *512 * 4 /1024 /1024 = 1m。

紋理的壓縮格式就是讓rgba的512*512 的資料,存在記憶體中,不要有1m那麼大,盡量的小。

(為什麼rgba的512*512 的.png是300k,不是1m,我理解就是相當於zip的感覺,被壓了,減少png對硬碟的儲存大小)

2.壓縮紋理格式 的作用就是,讓紋理儲存在記憶體中的大小盡量變小,又盡量保持精度。

3. 紋理儲存在記憶體中,先要顯示的話,就被傳到視訊記憶體中,都是opengl進行管理的。

參考:常用紋理和紋理壓縮格式  :

視訊記憶體與紋理記憶體詳解 . :

opengl占用記憶體計算 :

unity3d紋理壓縮格式表  :

unity載入模組深度解析之紋理篇                     

: 

Unity 紋理壓縮

紋理顯示到螢幕上,需要cpu和gpu協作完成。cpu對資源進行計算解碼,然後將紋理資料傳輸給gpu。gpu通過cpu的資料,將資料渲染到緩衝區。紋理壓縮減少了資源在cpu中進行解壓縮的過程。紋理壓縮減小了包體大小,減少了資料量級,減輕了頻寬計算的壓力。紋理壓縮時記憶體的使用效率更高。dxt格式是nv...

手遊中的紋理壓縮

移動裝置記憶體有限,為了節省記憶體,一般都會對貼圖進行壓縮。一張4mb的貼圖,在移動裝置中壓縮之後只有1 8 安卓裝置中算上alpha貼圖是1 4 也就是0.5mb。假如有一張1024px 1024px的4通道 rgba8888,每個通道都為8bit 貼圖。一般來說,一張紋理所占用的記憶體的計算方式...

WOW渲染中的紋理壓縮

一直沒玩台服,國服也停留在72級。成都的天氣一天天嚴峻,更是不想動了,於是用nvperfhud掛了下wow,看看它到底啥樣。用nvperfhud掛程式需要被掛的程式自身支援,但是網上有乙個老兄寫的乙個nvperfhud any程式可以幫你完成這個功能。對大多數d9的都有效。除非本身做了破解。完美時空...