关于DNF的多媒体包NPK文件的那些事儿(8) - DNF里的DDS图像
DDS是DirectDraw Surface的縮寫,實際上,它是DirectX紋理壓縮(DirectX Texture Compression,簡稱DXTC)的產物。DDS文件的紋理壓縮有很多方式,除了常見的DXTn外,也支持Mipmap, Cubemap, 和volume maps等更多的格式,但后者不會在這里介紹。
DDS文件數據包含一個固定128字節的DDS文件頭(不包含DXT10,DXT10還需要20字節的擴展頭,這里不討論)和圖像數據。DDS文件頭的格式如下:
| dwMagic | 4字節 1雙字 | DDS文件標識,固定為“DDS ”(有個空格), 即0x20534444。 |
| dwSize | 4字節 1雙字 | DDS文件頭大小(不包括標識的4字節),因此固定為124,即0x7C。 |
| dwFlags | 4字節 1雙字 | DDS文件標志位。有8個位有效(標☆的表示DNF中DDS文件所需要的標志位): 0x00000001:☆每個DDS文件都必須有。 0x00000002:☆每個DDS文件都必須有。 0x00000004:☆每個DDS文件都必須有。 0x00000008:若紋理數據是非壓縮,該位為1。 0x00001000:☆每個DDS文件都必須有。 0x00020000:若為Mipmap,該位為1。 0x00080000:☆若紋理數據是壓縮的,該位為1。 0x00800000:若紋理具有深度數據(適用于volume maps),該位為1。 DNF里所有DDS文件的標志位均為0x0081007。 |
| dwHeight | 4字節 1雙字 | 圖像高度(以像素為單位,一般是4的倍數) |
| dwWidth | 4字節 1雙字 | 圖像寬度(以像素為單位,一般是4的倍數) |
| dwPitchOrLinearSize | 4字節 1雙字 | 對非壓縮數據表示一行像素所需要的字節數; 對壓縮數據則表示整個圖像數據的字節數。 DNF里為后者。 |
| dwDepth | 4字節 1雙字 | 紋理具有深度數據時,表示紋理的深度。DNF里無用,固定為0。 |
| dwMipMapCount | 4字節 1雙字 | Mipmap層數,適用于Mipmaps。DNF里無用,固定為0。 |
| dwReserved1[11]; | 44字節 11雙字 | 官方用作保留位,但DNF里此字段第10個和第11個雙字分別為0x5454564E (“NVTT”字符串)和0x20008,并不明白其用途,估計是作為簽名或者另 一個標識符。 |
| ddspf | 32字節 8雙字 | DDS像素格式,是一個含有8個雙字的結構體,將在下文中描述。 |
| dwCaps | 4字節 1雙字 | 此字段用于指定紋理存儲的復雜度,有3個位有效(標☆的表示DNF中DDS 文件所需要的標志位) 0x00000008:復雜紋理(采用Mipmaps或Cubemap)。 0x00001000:☆紋理,每個DDS文件都必須有。 0x00400000:Mipmap格式。 |
| dwCaps2 | 4字節 1雙字 | 此字段用于指定紋理存儲的額外事項,包括Cubemap和Volume map的一些信息。 DNF里無用,固定為0. |
| dwCaps3 | 4字節 1雙字 | 官方用作保留位,DNF里為0。 |
| dwCaps4 | 4字節 1雙字 | 官方用作保留位,DNF里為0。 |
| dwReserved2 | 4字節 1雙字 | 官方用作保留位,DNF里為0。 |
?????? DDS像素格式是個含有8個雙字/32個字節的結構體,其含義如下:
| dwSize | 4字節 1雙字 | 這個結構體的字節數,也就是32(0x20) |
| dwFlags | 4字節 1雙字 | DDS圖像數據格式。有6個位有效(標☆的表示DNF中DDS文件所需要的標志位): 0x00000001:紋理包含透明通道,非壓縮數據適用。 0x00000002:某些舊的DDS文件才用的上。 0x00000004:☆采用壓縮數據,格式由FourCC決定。 0x00000040:紋理包含RGB通道,非壓縮數據適用。 0x00000200:某些舊的DDS文件才用的上。 0x00020000:某些舊的DDS文件才用的上。 DNF里有所DDS文件該字段均為0x4。 |
| dwFourCC | 4字節 1雙字 | 當采用壓縮數據時此字段才有效,可以是: 0x31545844:字符串DXT1,表示采用DXT1壓縮。 0x32545844:字符串DXT2,表示采用DXT2壓縮。 0x33545844:字符串DXT3,表示采用DXT3壓縮。 0x34545844:字符串DXT4,表示采用DXT4壓縮。 0x35545844:字符串DXT5,表示采用DXT5壓縮。 DNF采用的是壓縮數據,一般是DXT1/3/5。 |
| dwRGBBitCount | 4字節 1雙字 | 當采用非壓縮數據時此字段才有效,表示一個像素的RGB(估計也有透明通道) 所包含的位數。DNF里無用,為0。 |
| dwRBitMask | 4字節 1雙字 | 當采用非壓縮數據時此字段才有效,表示R通道掩碼。DNF里無用,為0。 |
| dwGBitMask | 4字節 1雙字 | 當采用非壓縮數據時此字段才有效,表示G通道掩碼。DNF里無用,為0。 |
| dwBBitMask | 4字節 1雙字 | 當采用非壓縮數據時此字段才有效,表示B通道掩碼。DNF里無用,為0。 |
| dwABitMask | 4字節 1雙字 | 當采用非壓縮數據時此字段才有效,表示透明通道掩碼。DNF里無用,為0。 |
?
在DDS圖像中,一般以4×4像素作為一個“塊”為單位來進行壓縮處理的。不同的DXT格式對塊的壓縮的方式也不同,壓縮效果也不同。
注:DXTn中均以2字節表示一個顏色,采用RGB565的存儲方式,即如下圖所示:
?????? DXT1采用8字節(2個雙字)來表示一個塊,因此針對ARGB8888像素的壓縮比是8:1。其原理是取這個塊中兩個顏色點(最大值和最小值)為關鍵色,然后通過線性插值的方式算出其他中間色,然后通過插值索引的方式確定每個像素使用的是哪種顏色。
?????? DXT1中,前兩個字節表示顏色1(color1),第三第四個字節表示顏色2(color2),剩下4個字節表示16個像素的所有的插值索引,也就是說每個像素有2位作為插值索引,因此每個像素的插值索引的取值為0到3(如下圖所示)。
?????? 當關鍵色color1>color2時,表示該塊不采用透明度存儲,因此將color1到color2的色域分為3等分,取中間兩點為color3和color4,通過每個像素的插值索引決定是哪個color。當關鍵色color1<color2時,表示該塊采用透明度存儲,此時將color1到color2的色域平分,取中間點為color3,而color4則表示透明像素。
?????? 由此可見,DXT1支持透明像素存儲,但不支持半透明像素存儲,對有半透明像素的紋理,應采用DXT2以上的版本。
?????? DXT2和DXT3采用16字節(4個雙字)來表示一個塊,針對ARGB8888像素的壓縮比是4:1。DXT2和DXT3分為兩個部分,低8字節是透明度通道部分,高8字節是顏色部分。顏色部分的數據存儲方式與DXT1一致,但DXT2的顏色部分是已經基于原色進行過透明度處理后的顏色,這一點是DXT2與DXT3的唯一不同之處。
?????? DXT2和DXT3中,低8字節直接存儲16個像素的透明度通道,因此每個像素的透明度通道是4位,范圍是0到255。由于透明度已經有數據進行存儲,因此在高8字節的顏色部分中,不再通過color1和color2的比較確定該塊是否使用透明度存儲,而是一致地使用DXT1中不采用透明度存儲時的算法。
?????? 由此可見,DXT2和DXT3支持了半透明像素的存儲,但是透明度范圍鎖定在全域,且只有16個值可以選,對精細的紋理,還是不足以滿足要求,而應采用版本更高的DXT4或DXT5。
?????? DXT4和DXT5跟DXT2和DXT3一樣,采用16字節(4個雙字)來表示一個塊,針對ARGB8888像素的壓縮比是4:1。也是分為兩部分,高8字節的顏色部分跟DXT2和DXT3一樣,但是低8字節的透明度通道部分,則采用跟顏色部分類似的線性插值算法,即取兩個像素的透明度作為關鍵透明度alpha1和alpha2,通過線性插值方式算出其他中間透明度,然后通過透明度插值索引方式確定每個像素的透明度。
?????? DXT4和DXT5中,第一字節表示第一個關鍵透明度alpha1,第二字節表示第二個關鍵透明度alpha2,其他6字節用于存儲16個像素透明度插值索引,因此每個像素的透明度插值索引為3位,即0-7。
?????? 當alpha1>alpha2時,將這段區間分為7等分,中間的6個點分別為alpha3、alpha4、alpha5、alpha6、alpha7、alpha8,然后通過透明度插值索引來確定該像素的透明度是哪個alpha值;當alpha1<alpha2時,則將這段區間進行5等分,中間4個點分別為alpha3、alpha4、alpha5、alpha6,而alpha7強制令為0,alpha8則強制令為255,這種存儲方式用于某些特殊的用途,比如某些具有實前景和半透明背景中,半透明的背景使用alpha1-alpha6,而實前景使用alpha8;或者某些透明背景中的半透明前景中,半透明的前景使用alpha1-alpha6,而透明背景使用alpha7;。
?????? DXT4和DXT5由于alpha值的范圍不平均分布在0-255之間,而是在某些特定的值之間(或者加上0和255),因此可以更好的實現透明度的平滑,適合存儲更精細的紋理。
?????? 在DNF中,有些具有實前景的技能特效(比如冰霜鉆孔車)一般都使用DXT1進行存儲,而帶有半透明的特效(比如杰克降臨后面的火焰,還有某些實體的外發光等)一般使用DXT5進行存儲。
總結
以上是生活随笔為你收集整理的关于DNF的多媒体包NPK文件的那些事儿(8) - DNF里的DDS图像的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机专业做产品,非计算机专业如何做产品
- 下一篇: w怎么接显示 树莓派zero_纯干货!一