Calculate Tangent Space是怎么计算切线的

 

Unity在FBX文件的导入设置中有一个关于切线(Tangents)的设置项,通常是使用默认的Calculate Tangent Space,让Unity自动计算切线,而无需美术人员在FBX文件中制作切线。这个切线信息是用于把切线空间的法线贴图中获取到的法线信息转换到世界空间的,大部分情况下,我们不关心这个切线算出来到底是个什么样子。但是在制作各向异性头发时,我们需要知道发丝的走向,通常是通过头发片元的副法线/切线来定义发丝的走向,那么Unity到底是基于什么来计算这个切线的呢?如何告知美术人员应如何制作用于头发各向异性的头发模型?

Calculate Tangent Space是怎么计算切线的_第1张图片

如上图所示,模型顶点的连线在法线贴图UV(通常是UV0)中的走向决定了是由副法线还是切线决定发丝的走向。

如果发丝从发根到发梢在UV中是从上到下的,那么片元的副法线就代表了发丝的方向。

如果发丝从发根到发梢在UV中是从右到左的,那么片元的切线就代表了发丝的方向。

我没有尝试发丝从下到上走或者从左到右走的时候,副法线/切线是否需要手动取反,亦或是已经由切线的W分量决定了其是否取反,有此需求的读者可以自行尝试一下。

与之相对的,垂直于UV图的向量也就是片元切线空间中法线的方向了,搞明白了这一点,我们再来看看法线贴图。

Calculate Tangent Space是怎么计算切线的_第2张图片

上图是从网上找的一张平凡无奇的法线贴图,不难发现,法线贴图的颜色通常都是分布在(127.5, 127.5, 255)附近。

把RGB颜色值除以255(映射到 0 ~ 1区间),再乘以2(映射到 0 ~ 2区间),然后再减1(映射到 -1 ~ 1区间),就转换成了一个单位向量(0, 0, 1),这个值的含义就是在切线空间中完全垂直于副法线和切线所夹的平面(也就是垂直于法线贴图的UV坐标系),即片元的法线本身,法线贴图不对其产生任何偏转。如果把这个(0, 0, 1)向量稍作偏转,那么它在法线贴图中的颜色就会发生细微的变换,通常我们不会在法线贴图中出现过于夸张的法线偏转,因为那会导致视觉效果的严重错误(偏转后的法线与表面实际朝向完全不符),这就是为什么法线贴图永远都是这么个色调,因为它永远只会出现在(127.5, 127.5, 255)附近。

明白了这个道理,就不难理解制作头发的时候为什么一定要确保头发丝在UV中的走向必须统一为上下或者左右了,不过在实际制作时,还是会犯一个错误,就是把头发面片的左右关系搞反,如上图所示,头发面片的左右关系必须对应UV中的左右关系,如果在UV中是从右到左排布,则模型的左对应UV的上,模型的右对应UV的下。如果搞反了左右关系,会导致副法线/切线的朝向与发丝的走向相反,渲染结果就是高光错乱不一,不是一个整体(总之看起来很奇怪)。 

Calculate Tangent Space是怎么计算切线的_第3张图片

如上图所示,黄字标注的1号面片的左侧(A点)对应了UV的左侧(A点),右侧(B点)对应了UV的右侧(B点),发丝走向正确(发根至发梢);黄字标注的2号面片的左侧(D点)对应了UV的右侧(D点),右侧(C点)对应了UV的左侧(C点),发丝走向反向(发梢至发根)。1、2两个面片的渲染结果不同,不能统一。

总结一下头发的制作规范就是:

1. 面片的正面(法线一面)规则平铺在UV中从上到下(或从右到左)。

2. 所有面片必须保证完全相同的UV走向,在UV中的平铺不能有正有反(即左对左右对右,或者从右到左走向时左对上右对下)。

3. 上下排布用副法线表示发丝走向,右左排布用切线表示发丝走向。

你可能感兴趣的:(Unity)