Contents

如何进行贴图的实时压缩

Contents

让我们暂时忽略具体的压缩算法实现,只考虑一个最基本的问题,如何让GPU生成一张压缩了的贴图。既然我们需要一张压缩了的贴图,那么首先,就应该以指定的压缩格式创建出一幅贴图,这没什么问题。然而遗憾的是,无论是pixel shader还是compute shader,通常都无法将数据写入压缩格式的贴图。

一种变通的方法是,第一步先把数据写入shader直接支持写入操作的格式的贴图中,如R32G32B32A32_UINT的贴图中,然后第二步进行数据类型的转换。

针对第一步,目前主流的GPU,都支持在shader中操作和写入整数类型的数据,所以在shader中按压缩格式编码贴图没有任何问题。

针对第二步,目前主流的API都提供了转换贴图格式的接口或方法,分别是:

  1. Windows:DX10.1及以上,使用CopyResource用一次拷贝转换格式
  2. Android:ES3.2及以上(Vulkan),使用CopyImageSubData用一次拷贝转换格式
  3. IOS:支持Metal就行,从MTLBuffer中创建MTLTexture作为RT,然后将MTLBuffer中的内容用copy复制到压缩格式的MTLTexture中

对于D3D12、Vulkan、Metal这些新一代API,应该可以用资源aliasing避免拷贝,还没有尝试 以上这些功能类似与C++中的reinterpret_cast,可以在保留数据的内容的前提下,按另一种格式来解释数据的内容,间接实现了在shader中写入压缩格式的贴图。