Compressed Image Formats

Compressed Image Formats

在程序中,消耗设备内存(device memory)最多的资源很可能是图像资源(image resources)。因此,vulkan提供了让图像压缩的能力。图像压缩能带来两个好处:

  • 减少了程序使用图像资源带来的内存消耗。
  • 较少了访问图像资源时的带宽。

现今vulkan使用的所有图像压缩格式都是块压缩格式(block compressed formats)。图像中的纹素(texels)被压缩成小的方形或矩形,并且可以独立的进行解压。虽然所有的压缩格式都是有损,并且相比jpeg和png格式都不具有竞争力。但是他们解压速度快,硬件实现便宜,能过直接进行纹素的随机访问也确实是他们的优势。

图像压缩格式是可选的,但是所有vulkan实现都需要至少支持一个格式系列。你可以检查接口vkGetPhysicalDeviceProperties()返回的VkPhysicalDeviceFeatures结构中的诸多字段来确定支持的是哪个系列的压缩格式。

如果textureCompressionBCVK_TRUE,那么设备支持块压缩格式,缩写为BC格式,BC格式系列包括:

  • BC1 : 由VK_FORMAT_BC1_RGB_UNORM_BLOCK,VK_FORMAT_BC1_RGB_SRGB_BLOCK,VK_FORMAT_BC1_RGBA_UNORM_BLOCKVK_FORMAT_BC1_RGBA_SRGB_BLOCK格式组成,BC1对图像的每个4x4纹素块进行编码,每块编码为64位。https://zhuanlan.zhihu.com/p/125751581


    这64位分成三个部分,由8个字节组成。

    \[c0_{lo},c0_{hi},c1_{lo},c1_{hi},bits_0,bits_1,bits_2,bits_3 \]

    前四个字节代表两个RGB颜色

    \[RGB_0 = c0_{hi}c0_{lo}\\ RGB_1 = c1_{hi}c1_{lo} \]

    每个RGB量中,高5位为R通道,接下来6位为G通道,低5位为B通道。

    后四个字节组成一个32位的颜色索引map,其中\(bits_3\)为高4位,\(bits_0\)为低4位。

    对于原图像中4x4的块,每一块中每一像素的位置由坐标表示\((x,y)\),其中\(x<4,y<4\),每一个坐标可以从\(bits\)中选出连续两位作为颜色索引:

    \[code(x,y) = bits[2 \times (4\times y+x)+1 ... 2\times (4\times y+x)] \]

    根据下图条件,我们就能得出位置\((x,y)\)对应的颜色。

    image

    对于含有alpha通道的图像,BC1使用最小的alpha压缩(即1位),值由下表决定。

    image

    当alpha为0时,编码成黑色。

  • BC2:由VK_FORMAT_BC2_UNORM_BLOCKVK_FORMAT_BC2_SRGB_BLOCK组成。BC2同样将图像分成4x4的块进行编码,每块有128位。BC2图像的RGB通道采用和BC1同样的编码方式,但是BC2的alpha通道每个纹素保留四位的alpha信息,保留在编码后的RGB数据之前。


    同样,64位的alpha数据看作一个整体,对于\((x,y)\)位置的alpha数据:

    \[code(x,y) = bits[4\times(4\times y+x)+3...4\times(4\times y+x)]\\ alpha(x,y) = \frac{code(x,y)}{15} \]

  • BC3:由VK_FORMAT_BC3_UNORM_BLOCKVK_FORMAT_BC3_SRGB_BLOCK组成,同样分成4x4的块进行处理,每块128位。前64位允许以比BC2更高精度存储alpha信息,后64位以类似BC1的方式压缩RGB信息。


    alpha的八个字节分别为

    \[alpha_0,alpha_1,bits_0,bits_1,bits_2,bits_3,bits_4,bits_5 \]

    前两个字节代表着两个基础的alpha值,通过乘上\(\frac{1}{255}\)转成alpha分量。

    后6个字节组成一个48位的索引map,\(bits_5\)位高4位。

    对于\((x,y)\)处的索引值,由:

    \[code(x,y) = bits[3\times(4\times y+x)+2...3\times(4\times y+x)] \]

    通过下表找到对应的alpha值。

    image

  • BC4:由VK_FORMAT_BC4_UNORM_BLOCKVK_FORMAT_BC4_SRGB_BLOCK组成。他们用于单通道的纹理(比如高度图),同样编码4x4块,每块64位。单通道数据的编码与BC3图像的alpha通道基本相同。

  • BC5:由VK_FORMAT_BC5_UNORM_BLOCKVK_FORMAT_BC5_SRGB_BLOCK组成,BC5系列是双通道格式,每个4x4块由两个背对背的BC4编码数据组成。

  • BC6:由VK_FORMAT_BC6H_SFLOAT_BLOCKCK_FORMAT_BC6H_UFLOAT_BLOCK组成,以上格式分别代表着有符号\无符号浮点压缩格式,每个4x4块的RGB纹素存储在128位的数据中。https://docs.microsoft.com/en-us/windows/win32/direct3d11/bc6h-format

  • BC7:由VK_FORMAT_BC7_UNORM_BLOCKVK_FORMAT_BC7_SRGB_BLOCK组成,他们是四通道格式,每个4x4块的RGBA数据存储在128位数据中。

如果textureCompressionETC2VK_TRUE,说明设备支持ETC格式,包括ETC2和EAC。该系列的格式包括

  • VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCKVK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:将4x4的RGB纹素块压缩成64位无符号格式。
  • VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCKVK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:将4x4纹素块加上1位的alpha数据压缩成64位无符号格式。
  • VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCKVK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:每个4x4的块压缩成128位,每个纹素都由4通道。
  • VK_FORMAT_EAC_R11_UNORM_BLOCKVK_FORMAT_R11_SNORM_BLOCK:有符号或无符号的单通道格式,将4x4块压缩成64位。
  • VK_FORMAT_EAC_R11G11_UNORM_BLOCKVK_FORMAT_EAC_R11G11_SFORM_BLOCK:有符号或无符号的双通道格式,将4x4块压缩成64位。

最后的一个系列是ASTC系列。如果textureCompressionASTC_LDRVK_TRUE,那么设备支持ASTC格式。你可能注意到所有的BC和ETC格式的块大小都是4x4纹素,但是根据格式不同,纹素的格式和用来存储的压缩数据的比特数也不同。

ASTC格式有些不同,他每块的比特数总是128位,并且所有的ASTC格式都有四个通道。ASTC格式的块大小是可变的,它支持:4x4,5x4,5x5,6x5,6x6,8x5,8x6,8x8,10x5,10x6,10x8,10x10,12x10,12x12。

ASTC格式的名字都用大致的格式——VK_FORMAT_ASTC_{N}x{M}_{encoding}_BLOCK{N}{M}代表着一块的宽和高,{encoding}UNORMSRGB,取决于数据是线性的还是编码为sRGB非线性的。比如VK_FORMAT_ASTC_8x6_SRGB_BLOCK是一种具有8x6块大小和SRGB数据的RGBA和ASTC压缩格式。

对于所有包括SRGB的格式,只有R,G,B通道使用非线性编码,A通道总是使用线性方式编码。

posted @ 2022-08-11 19:12  ᴮᴱˢᵀ  阅读(230)  评论(0)    收藏  举报