实时法线贴图dxt压缩算法

JMP van Waveren  id Software,Inc.        NVIDIA公司IgnacioCastaño

2008年2月7日

©2008,id Software,Inc.

抽象

原文下载地址  (有空补充)
注原文有代码,有需要可以看原文

     使用今天的图形硬件,普通地图可以存储在几种压缩格式中,这些格式在渲染过程中在硬件上

即时解压缩。对使用现有纹理压缩格式的几个对象空间和正切空间法线贴图进行评估。

虽然这些格式的解压缩在渲染过程中在硬件中实时发生,但是使用现有的压缩器可能需要大量时间

的压缩。提出了两种高度优化的切线空间法线贴图压缩算法,可以在CPU和GPU上实现实时性能。

介绍

凹凸映射使用纹理来扰乱表面法线,以使对象更具有几何复杂的外观,而不增加几何图元的数量。

如Blinn [ 1 ] 最初描述的,凹凸贴图在计算表面的照明之前,使用凹凸贴图高度场的梯度来扰动表

面衍生(方向向量)方向上的内插表面法线。通过改变表面法线,表面被点亮,好像它具有更多的

细节,结果也被认为比用于描述表面的几何图元具有更多的细节。

正态映射是凹凸映射的应用,由Peercy等引入 [ 2 ]。虽然凹凸贴图扰乱了对象的现有表面法线,但

是正常映射完全取代了法线。普通地图是存储法线的纹理。这些法线通常存储为具有三个组件的单

位长度向量:X,Y和Z.正常映射比凹凸贴图具有显着的性能优势,因为计算表面照明所需的操作

更少。

通常的映射通常在两个品种中找到:对象空间和正切空间法线映射。

它们在测量和存储法线的坐标系中不同。

对象空间法则映射相对于整个对象的位置和方向存储法线。

切线空间法线相对于三角形顶点的内插切线空间存储。

虽然物体空间法线可以是单位球体上的任何地方,但正切空间法线仅在表面前方的单位半球上,

因为法线总是指向表面。

对象空间法线贴图(左)
和切线空间中相同法线贴图(右)的示例。

正常并不一定必须存储为具有组件X,Y和Z的向量。

然而,从其他表示形式的渲染通常以性能成本来存储。

例如,通常可以存储为角度对(俯仰,偏航)。

然而,该表示具有内插或滤波不能正常工作的问题,

因为存在可能不存在用于表示局部旋转的角度的简单变化的方向。

在内插,滤波或计算该物体的表面照明之前,角度对必须转换为不同的表示,如矢量,

这需要昂贵的三角函数。

尽管法线贴图可以存储为浮点纹理,但是通常将法线贴图存储为有符号或无符号整数纹理,因为法向矢量的分量取值范围很广(通常为[-1,+1] ),并且在不浪费浮点指数的任何位的情况下,在整

个范围内具有相同的精度是有益的。例如,要将法线贴图存储为每个分量8位的无符号整数纹理,

X,Y和Z分量将从[-1,+1]范围内的实数值重新整数到[0, 255]。这样,实值向量[0,0,1]被转换成

整数向量[128,128,255],当被解释为RGB空间中的一个点时,是紫色/蓝色主要在切线空间法线贴

图 为了呈现存储为无符号整数纹理的法线贴图,矢量分量首先从一个整数值映射到硬件中的浮点

范围[0,+1]。

例如,在每个分量具有8位的纹理的情况下,通过与255分割将整数范围[0,255]映射到浮点范围[0,+1]。

然后,组件通常从[0,+1]范围在片段程序渲染过程中通过在与2相乘后减1后范围为[-1,+1]范围。

当使用有符号整数纹理时,从整数值到浮点数范围[-1,+1]直接在硬件中执

行。矢量分量首先从整数值映射到硬件中的浮点范围[0,+1]。例如,在每个分量具有8位的纹理的

情况下,通过与255分割将整数范围[0,255]映射到浮点范围[0,+1]。

然后,组件通常从[0,+1]范围在片段程序渲染过程中通过在与2相乘后减1后范围为[-1,+1]范围。

当使用有符号整数纹理时,从整数值到浮点数范围[-1,+1]直接在硬件中执行。矢量分量首先从整

数值映射到硬件中的浮点范围[0,+1]。

例如,在每个分量具有8位的纹理的情况下,通过与255分割将整数范围[0,255]映射到浮点范围

[0,+1]。

然后,组件通常从[0,+1]范围在片段程序渲染过程中通过在与2相乘后减1后范围为[-1,+1]范围。

当使用有符号整数纹理时,从整数值到浮点数范围[-1,+1]直接在硬件中执行。

是否使用有符号或无符号整数纹理,一个根本的问题是不可能从二进制整数到浮点范围[-1,+1] 导

线性映射,使得值-1,和+1表示准确。在先前的NVIDIA实现中使用的带符号整数纹理的硬件映

射并不完全代表+1。

对于n位无符号整数分量,整数0映射到-1,整数2 n-1映射到0,最大整数值

2 n -1映射到1 - 2 1-n。换句话说,值-1和0被精确地表示,但值+1不是。

用于DirectX 10类硬件的映射是非线性的。

对于n位有符号整数分量,整数-2 n-1映射到-1,整数-2 n-1 +1也映射到-1,整数

0映射到0,整数2 n-1 -1映射到+1。换句话说,值-1,0和+1都被精确地表示,但值-1表示两次。

旧硬件不支持签名纹理。此外,从二进制整数到范围[-1,+1]的映射可能是硬件特定的。一些实现

可能选择不完全代表+1,而传统的OpenGL映射指定-1和+1可以被精确地表示,但是0不能。其他

实现可以选择非线性映射,或允许超出范围[-1,+1]的值,使得可以精确地表示所有三个值-1,0和

+1。为了覆盖最广泛的硬件范围,没有任何硬件特定的依赖关系,这里使用的所有法线图被假设

存储为无符号整数纹理。从[0,+1]到[-1,+1]范围内的映射在片段程序中通过在乘以2之后减1来执

行。这可能导致附加的片段程序指令,当使用带符号的纹理时,可以将其简单地删除。这里使用的

映射与传统的OpenGL映射相同,这导致值-1和+1的精确表示,但不是0。

整数法线贴图通常可以按照每个法向量16(5:6:5),24(8:8:8),48(16:16:16)或96

(32:32:32)位存储。然而,今天的大部分普通地图都不存在每个法向量不超过24(8:8:8)

位。重要的是要认识到实际上接近单位长度的相对较少的8:8:8位向量。例如,在RGB空间中为

深蓝色的整数向量[0,0,64]不表示单位长度的法向量(长度为0.5而不是1.0)。

下图显示了比单位长度小于特定百分比的可表示的8:8:8位向量的百分比。

例如,如果法向量不被认为是单位长度大于5%的可接受的话,那么只有大约15%的可表示的8:

8:8位向量可用于表示法向量。

如5:6:5位那样精确度较低的位,接近单位长度的可表示向量的数量迅速减少。

为了显着增加可以使用的向量的数量,可以将每个法向量存储为不一定是单位长度的方向。然后,

这个方向需要在片段程序中进行归一化。然而,仍然有一些浪费,因为只有83%的所有8:8:8位向量表示唯一的方向。

例如,整数向量[0,0,32],[0,0,64]和[0,0,96]都指定完全相同的方向(它们是彼此的倍数)。

此外,独特的标准化方向不是均匀分布在单位球体上。

对于[-1,+1] x [-1,+1] x [-1,+1]向量空间的边界框的四个对角线的方向,有更多的表示方式,到坐标轴。

例如,在向量[1,1,1]周围的15度半径内表示的方向比在向量[0,0,1]周围15度半径内的方向表示三倍。

下图显示了投射到单位球体上的所有可表示的8:8:8位矢量的分布。

载体密度较低的区域为绿色,密度较高的区域为红色。

8:8:8位向量
投影在单位球体上的分布

在今天的图形硬件上,普通地图也可以以多种压缩格式存储,在渲染过程中实时解压缩。

由于减少的带宽要求,压缩的法线贴图不仅要求显卡内存少得多,而且通常还会比未压缩

的法线贴图快。

各种不同的方式来利用现有的纹理压缩格式的正常地图压缩,已被建议在文献[ 789 ]。

这些正常的地图压缩技术中的几个以及它们的扩展在第2节和第3节进行了评估。

虽然这些格式的解压缩是在硬件中实时完成的,但对这些格式的压缩可能需要相当长的时间。现有

压缩机设计为高质量离线压缩,而不是实时压缩[ 202122 ]。

然而,实时压缩对于从不同格式的代码转换法线图,动态生成的法线贴图的压缩

以及压缩的法线贴图渲染目标来说是非常有用的。

在第4节和第5节中,提出了两种高度优化的切线空间法线贴图压缩算法,

可用于实现CPU和GPU的实时性能。

对象空间正常图

对象空间法则映射相对于整个对象的位置和方向存储法线。

物体空间中的常规可以在整个单位球体上的任何地方,

并且通常存储为具有三个组件的向量:X,Y和Z.可以使用常规颜色纹理压缩技术存储对象空间法

线贴图,但是这些技术可能不会有效,因为法线贴图不具有与颜色纹理相同的属性。

2.1对象空间DXT1

DXT1 [ 34 ],也被称为在DirectX 10 BC1 [ 5 ],是用于颜色纹理一种有损压缩格式,以8:1的固

定压缩比为2:1。DXT1格式设计用于在渲染过程中对显卡硬件进行实时解压缩。DXT1压缩是块截

断编码(BTC)[ 6 ]的一种形式,其中图像被划分为非重叠块,并且每个块中的像素被量化为有限

数量的值。4×4像素块中的像素的颜色值通过RGB颜色空间在一行上的等距点近似。

该行由两个端点定义,对于4x4块中的每个像素,2位索引存储在该行上的一个等距点上。

通过颜色空间的线的端点被量化为16位5:6:5 RGB格式,并且通过插值生成一个或两个中间点。

DXT1格式允许通过根据终点的顺序切换到不同的模式,其中仅生成一个中间点并指定一个附加颜

色,这是黑色和完全透明的。

虽然DXT1格式是为颜色纹理设计的,但此格式也可用于存储法线贴图。为了将法线贴图压缩成

DXT1格式,法线向量的X,Y和Z分量映射到颜色纹理的RGB通道。

特别是对于DXT1压缩,每个法向量分量从[-1,+1]范围映射到整数范围[0,255]。

在光栅化期间,DXT1格式在硬件中解压缩,并且整数范围[0,255]映射到硬件中的浮点范围[0,1]。

在片段程序中,范围[0,1]将必须映射回范围[-1,+1]以执行法向量的照明计算。

以下片段程序显示了如何使用单个指令实现此转换。

#input.x = normal.x 
[0,1]
#input.y = normal.y
[0,1]
#input.w = 0
 
MAD正常,输入,2.0,-1.0

将法线贴图压缩成DXT1格式通常会导致质量相当差。有明显的阻塞和条带伪影。每4×4块只能编

码四个不同的法向量,这通常不足以准确地表示块中的所有原始法向量。因为每个块中的法线在一

行上用等距点近似,所以也不可能对每个4×4块的四个不同的法向量编码都是单位长度。

每4x4块只有两个法向量可以一次接近单位长度,通常一个压缩器通过向量空间来选择一个最小化

一些误差度量的一条线,使得这些向量实际上不接近单位长度。

右侧的DXT1压缩法线贴图
与左侧的原始法线贴图相比,显示出明显的块状伪影。

为了提高质量,可以将每个法向量编码为不一定是单位长度的方向。然后,该方向必须在片段程序

中重新归一化。以下片段程序显示了法向量如何重新归一化。

#input.x = normal.x 
[0,1]
#input.y = normal.y 
[0,1]
#input.w = 0
 
MAD正常,输入,2.0,-1.0
DP3标尺,正常,正常
RSQ scale.x,scale.x
MUL正常,正常,scale.x

编码方向使压缩机更自由,因为压缩机不必担心向量的大小,并且可以通过正常空间将所有可表示

向量的大部分百分比用于线路的终点。然而,这种增加的自由使压缩成为一个更难的问题。

DXT1压缩的 法线贴图 与 右侧的 原始法线贴图 相比,右侧 重新 归一化。

以上图片显示,尽管质量好一点,质量一般还是比较差。无论是否在片段程序中重新规范化,

DXT1压缩对象空间法线贴图的质量一般不被认为是可以接受的。

2.2对象空间DXT5

所述DXT5格式[ 34 ],也被称为在DirectX 10 BC3 [ 5 ],存储三个颜色通道中的相同的方式

DXT1确实,但没有1位alpha通道。代替1位alpha通道,DXT5格式存储与DXT1色彩通道相似的单独的Alpha通道。

4x4块中的alpha值通过α空间在一行上的等距点近似。

通过α空间的线的端点存储为8位值,并且基于端点的顺序,通过插值生成4或6个中间点。对于4个

中间点的情况,生成两个附加点,一个完全不透明,另一个用于完全透明。

对于4x4块中的每个像素,3位索引通过alpha空间或两个附加点中的一个存储

到该行上的等距点之一,用于完全不透明或完全透明。

使用相同数量的位来将alpha通道编码为三个DXT1颜色通道。

因此,与三维颜色空间相反,α通道以比每个颜色通道更高的精度被存储,因为α空间是一维的。

此外,总共有8个样本表示4×4块中的α值,而不是4个样本来表示颜色值。

由于额外的Alpha通道,DXT5格式消耗DXT1格式的内存量的两倍。

使用相同数量的位来将alpha通道编码为三个DXT1颜色通道。

因此,与三维颜色空间相反,α通道以比每

个颜色通道更高的精度被存储,因为α空间是一维的。此外,总共有8个样本表示4×4块中的α值,

而不是4个样本来表示颜色值。由于额外的Alpha通道,DXT5格式消耗DXT1格式的内存量的两

倍。使用相同数量的位来将alpha通道编码为三个DXT1颜色通道。因此,与三维颜色空间相反,α

通道以比每个颜色通道更高的精度被存储,因为α空间是一维的。此外,总共有8个样本表示4×4块

中的α值,而不是4个样本来表示颜色值。由于额外的Alpha通道,DXT5格式消耗DXT1格式的内存

量的两倍。总共有8个样本来表示4×4块中的α值,而不是4个样本来表示颜色值。由于额外的Alpha

通道,DXT5格式消耗DXT1格式的内存量的两倍。总共有8个样本来表示4×4块中的α值,而不是4

个样本来表示颜色值。由于额外的Alpha通道,DXT5格式消耗DXT1格式的内存量的两倍。

DXT5格式设计用于具有平滑alpha通道的颜色纹理。但是,此格式也可用于存储对象空间法线贴

图。特别地,可以通过使用DXT5格式并将其中一个组件移动到Alpha通道来实现更好质量的法线贴图压缩。

通过将其中一个组件移动到Alpha通道,该组件以更高的精度存储。此外,通过仅对DXT5格式的

DXT1块中的两个组件进行编码,这些组件的存储准确度通常也会得到改善。

对于对象空间法线图,由于法向量可以指向任何方向,

因此所有元素都可以以相似的频率发生,

所以没有明确的优点将任何特定的组件移动到alpha通道。

当对象空间法线贴图在特定方向上确实具有最多的向量时,将与该方向最正交的轴线映射到阿尔法通道显然是一个好处。

然而,由于每个编码需要不同的片段程序,所以通常在每个法线贴图上改变编码是不切实际的。以

下片段程序假设Z组件移动到alpha通道。

片段程序显示了组件如何从范围[0,1]映射到范围[-1,+1],而Z组件也从alpha通道移回原位。因

为每个编码都需要一个不同的片段程序。

以下片段程序假设Z组件移动到alpha通道。片段程序显示了组件如何从范围[0,1]映射到范围

[-1,+1],而Z组件也从alpha通道移回原位。

因为每个编码都需要一个不同的片段程序。以下片段程序假设Z组件移动到alpha通道。

片段程序显示了组件如何从范围[0,1]映射到范围[-1,+1],

而Z组件也从alpha通道移回原位。

#input.x = normal.x 
[0,1]
#input.y = normal.y 
[0,1]
#input.z = 0
#input.w = normal.z 

就像DXT1一样,没有重新规范化,这种格式导致片段程序中的最小开销

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值