二十八 Shader山下 切空间

以下摘录自《Unity 3D 开发实战详解》,18.1 。
如果要理解法线贴图的用法,就要知道 Space,即切空间 。什么是切空间?想象一下这样一个假设的情形:“2013年2月14日,上帝创造完世界之后,没错,他刚刚把世界造好,然后他让全世界70亿人民全体力争,昂首挺胸,双脚着地,头朝上,面朝南,报告一下此时太阳的方位 。”我可以肯定地告诉各位读者,会有70亿个不同的答案 。因为每个人都是以自己为原点,以从脚到脑袋指向天空的方向为z轴,以正前方为x轴,右手为y轴 。所谓的切线空间就是一个法线(从脚到头的方向)、切方向(双眼直视正前方)和(水平抬起你的右胳膊)这3个矢量构造了一个空间,然然后把这3个方向矢量,也就是当前像素位置的、、表示为一个矩阵,那么就是一个和类似的矩阵,乘以它就会得到某一个向量在当前位置切空间的表示,具体来说就是太阳对于当前这个人来说的角度 。这个时候,如果你在当前位置挖个坑,这坑的也就是从读取到的,此时你可以放心地用当前太阳方位来进行计算,不用担心有人提醒你太阳的角度不对 。记住,以你自己为中心所观察到的世界就是切空间 。
以下转载自知乎为什么要有切线空间( Space),它的作用是什么? 1 .什么是切线空间?
Space,其实一个坐标系,也就是原点+三个坐标轴决定的一个相对空间,我们只要搞清楚原点和三个坐标轴是什么就可以了 。在 Space中,坐标原点就是顶点的位置,其中z轴是该顶点本身的法线方向(N) 。另外两个坐标轴就是和该点相切的两条切线 。这样的切线本来有无数条,但模型一般会给定该顶点的一个,这个方向一般是使用和纹理坐标方向相同的那条(T) 。而另一个坐标轴的方向(B)就可以通过和的叉乘得到 。
【二十八Shader山下 切空间】

二十八  Shader山下 切空间

文章插图

二十八  Shader山下 切空间

文章插图

二十八  Shader山下 切空间

文章插图

二十八  Shader山下 切空间

文章插图

二十八  Shader山下 切空间

文章插图
通常我们所见的法线纹理还是基于原法线信息构建的坐标系来构建出来的 。那种偏蓝色的法线纹理其实就是存储了在每个顶点各自的 Space中,法线的扰动方向 。也就是说,如果一个顶点的法线方向不变,那么在它的 Space中,新的值就是z轴方向,也就是说值为(0, 0, 1) 。但这并不是法线纹理中存储的最终值,因为一个向量每个维度的取值范围在(-1, 1),而纹理每个通道的值范围在(0, 1),因此我们需要做一个映射,即pixel = ( + 1) / 2 。这样,之前的法线值(0, 0, 1)实际上对应了法线纹理中RGB的值为(0.5, 0.5, 1),而这个颜色也就是法线纹理中那大片的蓝色 。这些蓝色实际上说明顶点的大部分法线是和模型本身法线一样的,不需要改变 。总结一下就是,法线纹理的RGB通道存储了在每个顶点各自的 Space中的法线方向的映射值 。
2.为什么要有切线空间
实际上,法线本身存储在哪个坐标系中都是可以的,例如存储在World Space、或者 Space、或者 Space中 。但问题是,我们并不是单纯的想要得到法线,后续的光照计算才是我们的目的 。不管使用哪个坐标系,都面临着一个选择,就是最后光照计算使用的坐标系究竟是哪个 。对于-SpaceMap,我们一般就是在 Space里计算的,也就是说,我们需要把、在 中转换到 Space中,然后在 对法线纹理采样后,直接进行光照计算 。-Space还有如下一些优点:自由度很高 。-SpaceMap记录的是相对法线信息,这意味着,即便把该纹理应用到一个完全不同的网格上,也可以得到一个合理的结果 。可进行UV动画 。比如,我们可以移动一个纹理的UV坐标来实现一个凹凸移动的效果,这种UV动画在水或者火山熔岩这种类型的物体会会用到 。可以重用 Map 。比如,一个砖块,我们可以仅使用一张 Map就可以用到所有的六个面上 。可压缩 。由于-SpaceMap中法线的Z方向总是正方向的,因此我们可以仅存储XY方向,而推导得到Z方向 。