在学习法线贴图纹理的时候无法避免的遇到了切线空间的学习和理解的问题,在此记录下自己理解的过程。
1. 法线纹理的目的和存在的意义:
是在底模上表现出高模的各种凹凸细节,而为什么要表现凹凸细节呢,很简单,就是为了光照计算,模拟出高模的凹凸细节,光照的时候可以更加接近现实的质感。
如果直接在项目中使用高模的话就不存在这个法线纹理贴图的问题了,因为高模本身的细节足够细致,光照只需要按照模型本身的法线来计算就可以了。但是这样对性能影响很大,几乎99%以上的项目都需要将高模输出底模在运行时使用。
2. 法线贴图的两种类型:
模型空间下的法线纹理
在这个模式下,法线是在模型空间下的坐标系为参考系,存储在法线纹理贴图里面的。非常直观,但是也存在一些缺点,以下是优缺点列表:
- 实现简单
- 纹理坐标的缝合处和尖锐的边角处突变缝隙比较少,更加平滑
- 只能对于指定的模型进行贴图,没法很好的重用,因为法线信息是以绝对的方式被记录的,而且模型还不能随意变形。
切线空间下的法线纹理以下是优缺点列表:
- 自由度高
- 可以进行uv动画
- 可以重用
- 可以被压缩
- 纹理坐标的缝合处和尖锐的边角处突变缝隙比较多,不够平滑,但是这个误差一般都在人眼可接受的范围内
3. 切线空间
以上综述很容易得出一个结论,就是切线空间下的法线贴图比较常用和好用。但是不易于理解,因为他涉及到一个坐标变换问题。
理解的难点在于以下几点:
首先要理解,切线空间是每个点都有各自的切线空间,而被记录的法线在切线空间下表现为法线的扰动。
什么是法线的扰动呢?
一个模型是由很多个面组成的,而在这些面在高模的细节当中会出现凹凸起伏,但是在底模当中这些凹凸细节是被忽略的。改由法线贴图记录的切线空间的法线信息来替代这些凹凸信息被记录。
在Unity中或者是Cg中,规定纹理坐标的方向u和v作为切线和副切线的方向。
其扰动后的在切线空间中的坐标(x, y, z),其中x是u方向上的偏移,y是v方向上的偏移,z则是法线方向上的偏移。
将其作为颜色存储在法线贴图中。由于归一化之后的法线坐标,各分量范围在[-1, 1]之间,而颜色范围在[0, 1]之间。对其做(x+1)/2的映射计算,使其值满足颜色范围。
由于是偏移量,因此当表面凹凸没有变化时,法线为原法线方向(x y z) = (0, 0, 1)。映射到颜色之后为(0.5, 0.5, 1.0)。这也是为什么法线贴图大部分是偏浅蓝色的原因。
大家看到的那些非蓝色的部分恰恰就是凹凸部分的区域,由于凹凸发生了扰动。
需要注意的是,在使用切线空间下的法线纹理时,需要针对切线空间来做坐标换算,使得切线空间和世界空间做转换获得正确的光照结果。