当然也可以做6个法向图,每个面用自己的那个,也能解决这个问题,但是这样又会引入一些缺点,比如资源占用比较大,现在一般都不这样做了,那么只有一张法向纹理的情况下,是怎么实现在不同的面上能正确使用的呢?这里的关键点就在于,存储在里面的法向量的数据,它不是模型坐标系下的,直接读出来并不能使用。
切线空间
为了能实现法向量在不同的面上都能正确使用,引入了切线空间(Tangent Space)这个概念,特别注意一点,切线空间定义在每个三角面片上,切线空间通常也叫作TBN坐标系,T是切线(Tangent),B是副切线(BiTangent),N是法线(Normal),T与纹理坐标系的U轴相同,B与纹理坐标系的V轴相同,法向贴图中的RGB
颜色值读出来后,从01范围稍微转换一下到-11,就是对应切线空间中的xyz
:
tips:法向纹理中存储的法向量是切线空间下的,和模型具体如何旋转无法,大致都是指向切线空间的z轴方向,因此z分量也就是RGB的B分量一般要比其它2个分量要大很多,因此法向纹理通常看起来是偏蓝色的。
那么问题来了,既然法向贴图中的RGB
颜色值是表示切线空间中的xyz
,也就是说它是切线空间下的法向量,而光源位置、模型顶点都在模型坐标系下,怎样才能用这个切线空间下的法向量呢?那就要把他们转换到同一个坐标系下。这里就要用到线性代数的一个知识点,如果知道一组坐标基在另一个坐标系下的表示,那用这组坐标基下的坐标乘上这组坐标基在另一个坐标系下的表示,就可以将这组坐标基下的坐标转换到另一个坐标系下,听起来有点绕,给大家找了一个学习资料:zhuanlan.zhihu.com/p/69069042
具体到我们这里,TBN
就是一组在模型坐标系下的基向量,因此用TBN
去变换法向纹理中的法向量,结果就是得到了模型坐标系下的法向量,这样就都在同一个坐标系中,之后就可以使用了,比如都变换到世界坐标系中去。
那么如何计算得到TBN
三个向量呢?网上也有不少的推导文章,网上大多数文章的推导过程,是以T与U方向相同、B与V方向相同从而构造出2个纹理坐标转换到模型顶点坐标的方程,从而求解出T和B的,本篇文章也是类似