关于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的存储方式,即如下图所示:

关于DNF的多媒体包NPK文件的那些事儿(8) - DNF里的DDS图像_第1张图片


       DXT1采用8字节(2个双字)来表示一个块,因此针对ARGB8888像素的压缩比是8:1。其原理是取这个块中两个颜色点(最大值和最小值)为关键色,然后通过线性插值的方式算出其他中间色,然后通过插值索引的方式确定每个像素使用的是哪种颜色。

       DXT1中,前两个字节表示颜色1(color1),第三第四个字节表示颜色2(color2),剩下4个字节表示16个像素的所有的插值索引,也就是说每个像素有2位作为插值索引,因此每个像素的插值索引的取值为0到3(如下图所示)。

关于DNF的多媒体包NPK文件的那些事儿(8) - DNF里的DDS图像_第2张图片

       当关键色color1>color2时,表示该块不采用透明度存储,因此将color1到color2的色域分为3等分,取中间两点为color3和color4,通过每个像素的插值索引决定是哪个color。当关键色color1

       由此可见,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

       DXT4和DXT5由于alpha值的范围不平均分布在0-255之间,而是在某些特定的值之间(或者加上0和255),因此可以更好的实现透明度的平滑,适合存储更精细的纹理。

       在DNF中,有些具有实前景的技能特效(比如冰霜钻孔车)一般都使用DXT1进行存储,而带有半透明的特效(比如杰克降临后面的火焰,还有某些实体的外发光等)一般使用DXT5进行存储。

你可能感兴趣的:(关于DNF的多媒体包NPK文件的那些事儿(8) - DNF里的DDS图像)