
























本文大多数内容来自这两篇文章,看完后基本明白了法线贴图的种种细节。
顾名思义,法线贴图保存的是法线的信息贴图。
用来进行凹凸映射。
凹凸映射的目的是使用一张纹理来修改模型表面的法线,以便为模型提供更多的细节。这种方法不会真的改变模型的顶点位置,只是让模型看起来好像是“凹凸不平”的,但可以从模型的轮廓处看出“破绽”。
有两种主要的方法可以用来进行凹凸映射:一种方法是使用一张高度纹理(height map)来模拟表面位移(displacement),然后得到一个修改后的法线值,这种方法也被称为高度映射(height mapping);另一种方法则是使用一张法线纹理(normal map)来直接存储表面法线,这种方法又被称为法线映射(normal mapping)。尽管我们常常将凹凸映射和法线映射当成是相同的技术,但要知道它们之间的不同。

上图 左边: 模型空间下的法线纹理 右边: 切线空间下的法线纹理
法线纹理存储的是表面的法线方向。由于法线方向的分量范围在[-1, 1],而像素的分量范围为[0, 1],因此我们需要做一个映射,通常使用的映射就是:
pixel=(normal + 1) / 2
这就要求,我们在Shader中对法线纹理进行纹理采样后,还需要对结果进行一次反映射的过程,以得到原先的法线方向。反映射的过程实际就是使用上面映射函数的逆函数:
normal=pixel × 2 - 1
一旦从贴图里解压出来后,就可以直接用了,效率很高.但是有个缺点,这个world space normal 是固定了,如果物体没有保持原来的方向和位置,那原来生成的normal map就作废了。
对于模型顶点自带的法线,它们是定义在模型空间中的,因此一种直接的想法就是将修改后的模型空间中的表面法线存储在一张纹理中,这种纹理被称为模型空间的法线纹理(object-space normal map)。
对象空间的法线贴图,这个贴图中记录的法线信息是基于模型空间的,因此数值是相对的,这样模型在场景中是可以位移和旋转的,只要在计算的时候乘上对应的矩阵即可。而且从上面的图里可以看到贴图是彩色的,因为模型上的顶点法线在这个空间中是朝各个方向的。
对象空间的法线贴图比起世界空间的在使用了已经有了很大的进步,不过它仍旧有自己的局限性,就是这样的贴图还是依赖于模型本身。从其定义也可以看出来,它也是一种“绝对位置”。如果模型发生了形变,则这个贴图的信息就是错误的。从目前来看,我只能想到模型在场景中存在动画这个问题。
对于模型的每一个顶点,它都有一个属于自己的切线空间,这个切线空间的原点就是该顶点本身,而z轴是顶点的法线方向(n),x轴是顶点的切线方向(t),而y轴可由法线和切线叉积而得,也被称为副切线(bitangent, b)或副法线。这种纹理被称为是切线空间的法线纹理(tangent-space normal map)。
低模上的这个tangent space,也必须与高模上的坐标系tangent space。因为低模上的一个面,可能对应了高模上的几个面(精度高),按照新方法每个面都有一个局部坐标系,那对于低模上的每个面,高模因为存在好几个面,就会出现好几个局部坐标系,这肯定是不行的。所以高模所用的tangent space,就是低模上的。生成法线贴图,必定会确认高模上哪些面都对应低模上的哪个面,然后高模上的这几个面的法线,都会转换为低模这个面上所构建的tangent space的坐标。这样,当低模变形时,即三角面变化时,它的tangent space也会跟着变化,保存在贴图里的法线乘以低模这个面的tangent space到外部坐标系的转换矩阵即可得到外部坐标。顺便再提一点,高模保存的这个法线,是高模上object space里的法线。

此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。