这篇博客介绍了在延迟渲染(Deferred Rendering)中比较常用的一种用于优化单位向量在G-Buffer中储存的算法,该算法在Quake2、虚幻Ⅳ引擎中被运用。
读者可以在虚幻引擎Ⅳ的DeferredShadingCommon.usf
中接触到相应的代码,也可以阅读相关论文,传送门。
单位向量
在计算机图形学中单位向量的使用极为普遍,例如表面的法线向量、切线向量和光线相关的向量等。这样一来,很多的图形学的算法的时间&空间性能都取决于针对这些向量的读取、处理和写入的速度。
特别的是传输这些数据的带宽需求与G-buffer对于内存的需求在很多地方制约了GPU渲染的速度。
在现在的图形渲染管线中,3D的向量要么存在高带宽的寄存器(registers)中,要么存在中等带宽的计算机内存中,要么存在低带宽的磁盘中。针对于单位向量,寄存器由于对速度有着极高的要求,往往希望你能够将其以float32*3
的形式进行单位向量的储存,而磁盘往往更希望更有效地利用存储空间,因此会鼓励你进行各种的编码/解码操作。
但是针对于在内存(或者芯片上的cache)中的存储,往往需要在速度和存储空间上取得一个平衡。因此可以考虑将单位向量进行某种程度的编码和解码,当然这种编码和解码也不能太复杂或者损失太多信息。
问题的提出和思路
这个算法的目的是如何编码一个单位向量的同时,能够让其占用最少的位数以及让信息损失量达到一个可接受的程度;或者说如何在一个固定的带宽限制下,尽量最小化损失的信息。
正常的表现方法以及分析
先看看单位向量的最普通的表现方法:一个包含三个32-bit的浮点数的结构体:
struct{
float x, y, z;}
那么它所占用的储存空间为: 3∗4∗8=96 bits。
可知的是,这种表现方法的域实际上是整个3D空间,