会员: 密码:  免费注册 | 忘记密码 | 会员登录 网页功能: 加入收藏 设为首页 网站搜索  
游戏开发 > 程序设计 > 3D图形
貼圖壓縮簡介
发表日期:2007-01-25 17:55:09作者: 出处:  

文档内容:
[Part 1]

貼圖是在 3D 場景中,增加真實性的一個重要的工具。就像一般的影像一樣,貼圖的大小愈大,它的圖像就愈精細。事實上,貼圖往往需要比一般的影像更大。因為,在 3D 場景中,觀察者可能會很靠近貼圖,使得貼圖需要放大很多倍,而造成模糊的現象。所以,一般來說,如果可能的話,貼圖愈大就愈好。

不過,貼圖是非常佔用記憶體空間的。現在的貼圖都是以不壓縮的形式存放在顯示記憶體中,而目前常用的貼圖格式是 16 bits、24 bits 和 32 bits。下表列出一些貼圖大小所佔用的空間:

貼圖大小 16 bits 16 bits mipmap 24 bits 24 bits mipmap 32 bits 32 bits mipmap
64x64 8 KB 10.6 KB 12 KB 16 KB 16 KB 21 KB
256x256 128 KB 170 KB 192 KB 256 KB 256 KB 340 KB
1024x1024 2 MB 2.6 MB 3 MB 4 MB 4 MB 5.3 MB

現在一般的顯示卡上通常裝有 32MB 的顯示記憶體。如果每個貼圖都要 2MB 的話,即使不計 frame buffer 所佔用的空間,也只能使用 16 張貼圖。這顯然是不可接受的。所以,現在的遊戲通常無法使用很大的貼圖。

然而,在儲存一般的影像的時候,通常會使用某些壓縮方式。現在常見的 JPEG 壓縮,可以達到 1:6 甚至 1:12 的壓縮比。如果把類似的壓縮方式應用在貼圖上,不就可以大量減少貼圖所用的空間了嗎?

不幸的是,一般的影像壓縮方式,是沒有辦法用在貼圖上面的。因為,顯示晶片在存取貼圖時,是一種「隨機存取」的動作。也就是說,顯示晶片通常會需要以任意的順序存取貼圖裡的資料。一般的壓縮方式如 JPEG,都利用了 variable length 的 coding,簡單的說,它們必需以一定的順序才能解開。因此,不能用這種方式來壓縮貼圖。

一種壓縮方式,是改變顏色空間。例如,3dfx 的 YAB 格式,就是一種不同的顏色空間。利用 YAB,每個像點只需要 8 bits,就可以達到接近 16 bits 的效果。不過,無論如何,這樣都使顏色的數目減少。因此,整個貼圖的色彩變化就受到了限制。

另一種方式,就是用傳統的「調色盤」結構。利用一個 256 種顏色的調色盤,就可以把貼圖以 8 bits 的方式儲存。不過,雖然它的色彩空間較大(可以是 24 bits 或 32 bits),但是總顏色數目還是不能超過 256 種。所以,它的應用範圍仍然有限。

現在常用的貼圖壓縮方式,則是利用以區塊為基礎的方式。通常的做法是,把貼圖切割成許多小區塊,再對各個區塊進行壓縮。例如,S3TC 就是把貼圖切成 4x4 的小區塊。利用這種做法,就可以對區塊進行某種處理(通常就是 vector quantization 或是其變形),顯示晶片也可以區塊為單位,進行隨機的存取動作。因此,這是適合用在貼圖的方式。

不過,區塊的大小會影響到壓縮的效果。一般來說,區塊愈大,就能有愈高的壓縮比。不過,愈大的區塊也會使額外的負擔增加。因為顯示晶片只能以區塊為單位來讀取貼圖資料,如果區塊愈大,則每個區塊中就可能會有愈多的資料是不需要的。所以,也不能任意把區塊的大小加大。

接下來的文章中,會簡單介紹一些常見的貼圖壓縮方式。


[Part 2]

在這一篇文章中,我們會介紹一種簡單的貼圖壓縮方式:VQTC。

VQTC 是由 NEC/Videologic 的 PowerVR 系列所使用的一種貼圖壓縮方式,但是因為 PowerVR 系列一直沒有得到很大的成功,所以 VQTC 一直未受到重視。而現在 Videologic 最新的 Kyro 顯示晶片也不再支援 VQTC。不過,因為 VQTC 相當簡單,所以還是簡單做個介紹。

VQTC 是使用 vector quantization 的方式,所以叫 VQTC。它的原理是:把貼圖切成許多相同大小的區塊(例如 2x2 或 4x4),對這些區塊做 vector quantization。例如,可以從這些區塊中,找出 4096 個最具代表性的區塊。這樣一來,每個區塊就只需要存放 index,也就是 12 bits 的空間。

顯示晶片在讀取貼圖資料時,要先將整個向量(即 4096 個區塊)讀入顯示晶片中的一個向量表。這個動作對每個貼圖只需要做一次。在讀取各個 texel 時,則是先判斷出所需的 texel 所在的區塊(以 2x2 的區塊來說,就是把位置座標分別除以二),讀取 index,再從向量表中查出區塊的內容。基本上,這些動作都非常簡單。

在壓縮比方面,以上面的例子來說,如果使用 256x256 32bpp 的貼圖,並使用 2x2 的區塊,那麼貼圖就有 128x128 = 16384 個區塊。找出 4096 個最具代表性的區塊後,整個貼圖需要的空間就是 4096 個區塊再加上 16384 個 index 的空間,即 4096x16 + 16384x1.5 = 88 KB。和原來未壓縮所需要的 256KB 相比,它的壓縮比約為 1:2.9。

如果是更大的貼圖,則可以使用更大的區塊(例如 4x4),不過,這樣會使品質變差。但是,經由選擇不同的區塊大小,和區塊的數目,就可以調整出品質和壓縮比的平衡點。這是 VQTC 的優點之一。

不過,VQTC 並非沒有缺點的。事實上,VQTC 最大的缺點,就是「不能做部分更新」。簡單的說,如果想要更新一個 VQTC 貼圖中的一小部分,幾乎可以說是不可能的,除非將貼圖重新壓縮,或是犧牲一些品質,使用原有的向量來壓縮。當然,對大部分的情形來說,這並不是個嚴重的問題;因為需要做部分更新的情形,通常是相當少見的。

另外,VQTC 也不太適合處理有「透明度」(即 alpha channel)的貼圖。一般來說,如果貼圖中有 alpha channel,會對 VQTC 的品質造成影響。

VQTC 現在已經不常用了(也許只在 Dreamcast 遊戲機中還被使用)。目前最流行的貼圖壓縮,則是由 S3 所開發的 S3TC。我們會在下一篇文章中介紹這個方法。


[Part 3]

這篇文章將會簡單介紹有名的 S3TC 貼圖壓縮方式。

S3TC 是由 S3 公司所發展出來的,最早用在它的 Savage 系列顯示晶片中。雖然 Savage 顯示晶片並不算成功,但是 S3TC 卻因為微軟公司將其加入 DirectX 而變得相當成功。微軟向 S3 授權 S3TC 技術後,其它公司若在 DirectX 中支援 S3TC(在 DirectX 中稱為 DXTC),則不需另外再付給 S3 費用,因此得到了相當程度的支援。

S3TC 包括五種貼圖壓縮格式,在 DirectX 中,分別稱為 DXT1 ~ DXT5。這些不同的貼圖壓縮格式,其實就是為了透明度(即 alpha channel)所設計的。

DXT1 是 S3TC 中,最基本的壓縮格式。它是用來處理「沒有 alpha channel」或是「alpha channel 為 1 bit」的貼圖。其它的壓縮方式都是只是 DXT1 的變化而已。

DXT1 所用的方法,和 VQTC 類似,也是將貼圖切成許多小區塊,然後再利用 vector quantization 的方式來壓縮。不過,和 VQTC 不同的是,DXT1 的區塊總是 4x4 的大小,而且它將 vector quantization 用在區塊內,而不是像 VQTC 對所有的區塊做 vector quantization。

對每個 4x4 的區塊,儲存了兩個 16 bits 的顏色,顏色的格式是 5-6-5 的 RGB。從這兩個顏色,可以用線性內插的方式,得到另外兩個顏色。簡單的說,如果這兩個顏色分別是 RGB0 和 RGB1,那 RGB2 和 RGB3 可以由下面的式子求出:

  • RGB2 = (2 * RGB0 + 1 * RGB3) / 3
  • RGB3 = (1 * RGB0 + 2 * RGB3) / 2

這樣就得到了四個顏色。區塊中的每個 texel 則是以一個 2 bits 的 index 表示。如果 index = 0,則表示這個 texel 的顏色是 RGB0;index = 1 則是 RGB1;index = 2 則是 RGB2;index = 3 則是 RGB3。以這樣的方式儲存,每個區塊只需要 16x2 + 2x4x4 = 64 bits。因此,在壓縮 16 bits 的貼圖時,壓縮比是 1:4。

DXT1 同時也可以處理「具有 1 bit alpha channel」的貼圖。一般來說,在貼圖中使用 1 bit 的 alpha channel,就是用來註明「透明」的地方。因此,DXT1 的處理方式,是犧牲一個顏色,用它的表示「透明」的 texel。

如果一個區塊需要存放透明色的話,那麼,顏色的產生方式,就變成:

  • RGB2 = (RGB0 + RGB1) / 2

和前面一樣,texel 的 index 仍是 2 bits。index = 0 ~ 2 時,分別是表示 RGB0 ~ RGB2。當 index = 3 時,就表示這個 texel 是「透明」的,它的顏色是黑色,且 alpha = 0。

不過,要怎麼區分「有 alpha」和「沒有 alpha」的情形呢?DXT1 使用了一個簡單的方法:如果 RGB0 比 RGB1 要大的話,那就表示區塊是沒有 alpha 的。相反的,就表示有 alpha channel 了。

當 alpha channel 不只是 1 bit 時,就需要其它的方式了。DXT2 ~ DXT5 就是在處理這種情形。因為它的原理和 DXT1 是相同的,所以就不再多介紹了。不過,DXT2 ~ DXT5 每個 4x4 區塊需要 128 bits,也就是說,它們的壓縮比只有 DXT1 的一半。

因為 S3TC 是針對每個 4x4 的區塊做壓縮,所以可以對貼圖做「部分更新」的動作。要更新貼圖中的某些部分,只要需更新這些部分的區塊即可,其它的區塊則完全不會被影響。所以,「部分更新」是很容易做到的。

在下一篇文章中,會簡單介紹 3dfx 的 FXT1 貼圖壓縮。


[Part 4]

在這篇文章中,會簡單介紹 3dfx 的 FXT1 貼圖壓縮技術。

基本上,FXT1 和 S3TC 是非常類似的。不過,FXT1 使用 8x4 的區塊,而非 S3TC 的 4x4 區塊。而且,相對於 S3TC 只有一種壓縮方式(即 DXT1,DXT2 ~ DXT5 只是將 DXT1 加上 alpha channel 而已),FXT1 有四種不同的方式。這使得在壓縮的時候,可以針對不同的情形,使用最適當的壓縮方式。

FXT1 有四種壓縮方式,都是使用 8x4 的區塊。第一種方式稱為 CC_HI,用來壓縮使用 1 bit alpha channel 來表示「透明 texel」的貼圖。

CC_HI 和 DXT1 非常類似,它也是存放兩個顏色。不過,和 DXT1 不同的是,CC_HI 用的是 15 bits 5-5-5 RGB 的格式,而不是 16 bits 5-6-5 RGB 的格式。

利用線性內插的方式(類似 DXT1 的方式),CC_HI 的兩個顏色會內插出五個顏色,合起來是七個顏色,再加上一個顏色表示「透明 texel」。每個 texel 則使用 3 bits 的 index 來指向這八個顏色。另外,CC_HI 使用 2 bits 的 mode bits 來表示這個區塊是 CC_HI 格式。所以,一個 8x4 的區塊需要 2 + 2x15 + 32x3 = 128 bits。因此,如果貼圖是 16 bits 的話,壓縮比就是 1:4。

第二種方式稱為 CC_CHROMA,它是專門用來存放沒有 alpha channle 的貼圖。基本上,CC_CHROMA 的方式很簡單:它存放四個 15 bits 的顏色,每個 texel 則用一個 2 bits 的 index 指向這四個顏色。它的 mode bits 是 3 bits,還有一個未使用的 bit,所以它需要的空間是 3 + 1 + 4x15 + 32x2 = 128 bits。

第三種方式稱為 CC_MIXED,這個模式非常的複雜。它將 8x4 的區塊分成兩個 4x4 的小區塊,每個小區塊有兩個 16 bits 5-6-5 RGB 的顏色。每個小區塊中的壓縮方式則和 DXT1 幾乎是相同的,但是它不是用顏色的大小來區分「是否有 alpha channel」,而是用一個 alpha bit 來區分。這個模式需要的空間也是 128 bits。

第四種方式則是 CC_ALPHA,是用來處理具有多位元 alpha channel 的模式(類似 DXT2 ~ DXT5)。它使用三個 20 bits 5-5-5-5 ARGB 格式的顏色,並有兩種模式:第一種模式,每個 texel 的 index(2 bits)指向這三個顏色,而第四個顏色則是表示「透明 texel」。第二種模式,則是將區塊分成兩個小區塊,並使用類似 DXT1 的方式(第一個小區塊用 COLOR0 和 COLOR1 為基礎色,而第二個小區塊則用 COLOR1 和 COLOR2 為基礎色),只不過有加上 alpha channel。這個格式的 mode bit 是 3 bits,再加上一個「模式 bit」,所以需要的空間是 3 + 1 + 20x3 + 32x2 = 128 bits。

基本上,FXT1 的壓縮比和 S3TC 並沒有很大的差別,但是一般來說,效果(特別是壓縮 24 bits 或 32 bits 的貼圖)則比 S3TC 要好一些。不過,它的區塊較大,也會使顯示晶片在處理時的效率較差。

FXT1 和 S3TC 都有相對應的 OpenGL extension 來提供支援。所以,如果想要取得更詳細的資料,可以到 OpenGL® Extension Registry 網站取得。S3TC 的 extension 稱為 GL_EXT_texture_compression_s3tc,而 FXT1 的 extension 則稱為 GL_3DFX_texture_compression_FXT1。在 extension 的文件中,有詳細的格式說明。

返回顶部】 【打印本页】 【关闭窗口

关于我们 / 给我留言 / 版权举报 / 意见建议 / 网站编程QQ群   
Copyright ©2003- 2024 Lihuasoft.net webmaster(at)lihuasoft.net 加载时间 0.0024