|
DXT1格式压缩高质量法线贴图
---法线延长算法
DXT1格式的压缩比是3Dc或DXT5的两倍,使用DXT1贴图可以成倍提高显卡总线和CACHE的效率,极大地提高性能。
可是如果不加任何处理地压缩法线贴图,会产生严重的马赛克。
我最近想到了一个DXT1存储高质量法线贴图的简单算法,命名为法线延长法,既有DXT1的高性能,又有较高质量。
算法
法线贴图一般是和漫反射贴图成对使用的。对两幅贴图的各级mipmaps逐像素进行以下处理:
(伪代码。因为是预处理所以使用double没关系)
double3 iNORMAL : 输入的法线贴图
double3 iCOLOR : 输入的漫反射贴图
double3 oNORMAL : 输出的法线贴图
double3 oCOLOR : 输出的漫反射贴图
double l = max( iNORMAL.x , iNORMAL.y , iNORMAL.z );
oNORMAL = iNORMAL / l;
oCOLOR = iCOLOR * l;
再找个nvDXT之类的高质量DXT压缩工具一压就可以当作普通的法线贴图和漫反射贴图用了,只是使用时千万不要进行单位化。
效果对比
见后面所附图片
分析
直接压缩成DXT1会产生马赛克的原因并不是DXT1精度不够,而是因为法向量的单位化。
DXT1是用双16位色进行插值的,每像素存了两位的插值权值,这样共有2^18种取值。
但是对于法线贴图其中只有长度为1的取值有用。例如切空间法线贴图Z的取值是由XY的取值唯一确定的。这样,XY的取值只有在单位圆以内的那些点即只有 2^5*2^6*PI/4 = 1068种取值。
而经过法线延长处理后压缩的法线贴图,XYZ中必然有一个绝对值为1
Z= 1 时有 2^5*2^6 =2^11 种取值
X= 1 时有 2^5*2^6/2 =2^10 种取值
X=-1 时有 2^5*2^6/2 =2^10 种取值
Y= 1 时有 2^5*2^5/2 =2^9 种取
Y=-1 时有 2^5*2^5/2 =2^9 种取值
共5120种取值范围扩大了许多。
总结讨论
法线延长算法实现简单,但却使dxt1压缩法线成为可能,极大地提高了显卡总线和CACHE的效率。
省略了向量单位化过程,在sm1.0以前这还是很大的开销。
抛砖引玉而已。
更进一步,如果有一种编码方法能把2^18种取值都用于存储法线那就更精确了。
例程
命令行下的处理程序,含源程序,输入输出均为R8G8B8格式的DDS文件.
格式
textconv 输入法线贴图文件名 输入漫反射贴图文件名 输出法线贴图文件名 输出漫反射贴图文件名
例如:
textconv iNORMAL.DDS iCOLOR.DDS oNORMAL.DDS oCOLOR.DDS
然后请再用压缩工具将输出文件转化成DXT1格式,推荐使用NVDXT。
但是注意最好不要使用这个工具自动生成的mipmaps。
如果有什么问题
请联系
zhouhe@163.com
我目前还在上大学,毕业之前还会发几篇算法:
《法线扰动---预处理实现动态"radiosity"》《几种光照贴图的比较》 |
|