几年来,我试图了解法线贴图以及在使用它们时通常出现的问题。
我发现的大多数解释太技术性,不完整或太复杂,以至于我无法理解,因此我决定尝试解释我收集的信息。 我了解这些解释可能不完整或不完全准确,但是我还是会尝试的。
第一个人造3D模型看起来像这样:
很好,但是这样的模型有一个明显的局限性:它看起来太多边形了。
最明显的解决方案是:添加更多的多边形,使曲面更加均匀和平滑,直到这些多边形显示为单个平滑曲面为止。 但是事实证明,要使像球体这样的表面光滑,就需要大量的多边形(尤其是今天)。
需要不同的解决方案,因此发明了法线。 (它不是那样发生的,但是更容易解释和理解。)
让我们沿着垂直于多边形表面的多边形中心进行追踪。 我们给这行一个非常不寻常的名字:正常。 法线的目标是控制表面指向的位置,以便当光线从该表面反射时,可以使用法线来计算所得的反射。 当光线照射到多边形时,我们将光线的角度与多边形的法线进行比较。 光束相对于法线方向以相同角度反射:
换句话说,光的反射将相对于多边形的法线对称。 这就是现实世界中大多数反射的工作方式。 默认情况下,光线从所有多边形完全垂直于其表面反射(就像在现实生活中一样),因为默认情况下多边形法线垂直于多边形表面。 如果法线中存在间隙,则我们会将它们视为独立的表面,因为光将在一个方向或另一个方向上反射。
如果两个面连接在一起,则可以要求计算机平滑一个多边形的法线到另一个多边形的过渡,以使法线根据多边形的最近法线逐渐对齐。 因此,当光线恰好照射到一个多边形的中心时,它将根据法线方向直接反射。 但是在多边形之间,此法线方向是平滑的,从而改变了光的反射。
我们将过渡视为单个表面,因为光将以平滑的方式在一个多边形和另一个多边形之间反射,并且它们之间没有间隙。 实际上,就像我们有许多多边形一样,光会平滑地反射出这些多边形。
这是我们通过设置平滑组(3ds Max,Blender)或将边缘指定为硬或平滑(Modo,Maya)来控制的:我们告诉程序哪些面之间的过渡应该是平滑的,哪些应该是硬的。
这是一个包含288个多边形的球体的比较,它们具有硬和平滑的过渡:
潜在地,我们可以指定类似平行六面体的形状,以便其所有顶点具有平均法线。 3D编辑器将努力使其表面光滑,以使其看起来像单个光滑表面。 对于3D编辑器来说,这是很合逻辑的,但看起来却很奇怪,因为我们有一个对象显然应该有几个单独的表面(盒子的每个面),但是,程序尝试将它们显示为一个光滑的表面。
这就是3D编辑器通常有一个用于平滑角度的参数的原因:如果我们有两个连接的多边形,其角度超过了平滑角度,则它们的过渡将是平滑的,而以小于平滑角度的角度连接多边形将是刚性的。 因此,在现实世界中,表面之间的陡峭角度将显示为不同的表面。
因此,我们使用法线来控制模型面之间的过渡,但是您可以走得更远。
由于我们正在改变光从对象反射的方式,因此我们还可以使非常简单的对象反射复杂的光。 这称为法线贴图。 我们使用纹理来更改从3D对象反射的光的方向,使其看起来比实际的要难。
现实世界中的一个例子是以前在购买薯片时作为礼物赠送的全息图(至少在西班牙是这样)。 它们是完全平坦的,但是它们像3D对象那样反射光,因此比实际困难得多。 在3D图形世界中,此方法效果更好,但仍然有其局限性(因为表面保持平坦)。
尽管我们使用多边形法线来实现某种黑魔法,但实际上,我们不使用多边形法线来控制模型表面的平滑。 我们使用顶点法线来控制法线的平滑。 从本质上讲,想法是相同的,但稍微复杂一点。
每个顶点可以与一个或多个法线关联。 如果它具有一个法线,则可以将其称为顶点的平均法线,如果有多个-则称为顶点的除法线。
让我们以边缘连接的两个多边形为例。 如果两个面之间的过渡是平滑的(如果我们在Maya / Modo中将其指定为平滑,或者在Max / Blender中都具有相同的平滑组),则每个顶点都有一个法线,这是多边形的平均法线(这就是为什么将其称为顶点的平均法线) ) 重要说明:直到最近,每个3D编辑器都使用其自己的方法来计算顶点的平均法线,也就是说,在一个程序中另一个程序中计算的法线贴图可能看起来完全不同。 我将在本教程的第二部分中告诉您更多信息。
如果过渡很困难(硬边或不同的平滑组),则每个顶点都有多个法线:每个连接的顶点根据其法线对齐。 在这种情况下,法线之间会形成一个间隙,看起来像两个不同的表面。 这就是所谓的分割顶点法线。
您可能会猜到,如果我们要控制法线贴图,则顶点法线控制非常重要。 幸运的是,我们不必直接更改法线甚至不必查看法线,但是了解法线的工作原理将有助于您理解为什么我们要进行这项工作,并更好地理解我们可能遇到的问题。
烘焙法线贴图时,我们实质上是告诉程序更改低多边形模型的法线遵循的方向,以便它们与高多边形模型中的方向相对应。 因此,lowpoly模型将以与highpoly相同的方式反射光。 所有这些信息都存储在称为法线贴图的纹理中。 让我们来看一个例子。
假设我们有这样的低聚模型(lowpoly)。 具有UV设置的四顶点平面,烘焙程序将使用该平面创建法线贴图。
而且她需要从此highpoly模型中获取有关法线的信息,该法线的法线更为复杂。
请记住,我们仅传输有关法线的信息,即UV,材质,拓扑,变换等。 不相关。 公认的规则:如果highpoly模型看起来不错,则其法线也很好,应该适合烘焙。
烘焙程序采用低多边形法线模型,并按照低多边形法线的方向发出光线(这就是为什么我们需要控制低多边形法线的原因)。 这些射线的长度是有限的,因此不能从远处的边缘获得正常的信息(通常将此距离称为烘烤距离或笼式距离)。 当这些光线与高多边形碰撞时,烘焙程序将计算如何反射这些光线,使它们遵循高多边形法线的方向,并将此信息存储在法线贴图中。
这是我们的示例的烘焙结果:
引擎使用了一种纹理来更改低多边形法线,以使光线像从高多边形版本中反射一样从此低多边形模型反射。 不要忘记,这只是一个不会影响lowpoly模型轮廓的纹理(如果光线不落在该模型上,则无法更改光线从模型反射的方式)。
尽管很明显可以通过法线贴图的外观“计算”高多边形的外观,但很明显,法线贴图不是普通纹理,因为它们存储的不是颜色信息,而是法线信息。 这也意味着法线贴图不能视为普通纹理。 此外,我们将看到,它们具有特殊的压缩和伽马校正参数。
您可以将法线贴图感知为一组存储在一个图像中的灰色阴影的三个纹理:
第一张图像告诉引擎此模型应如何反射右侧入射的光; 它存储在法线贴图的红色通道中。
第二个图像告诉引擎模型应如何反射从下面*入射的光; 它存储在法线贴图的绿色通道中。
*在某些程序中,光线不是从下方落下,而是从上方落下,也就是说,可能会有“左侧”和“右侧”法线贴图。 稍后我们将看到,这可能会引起一些问题。
第三个图像告诉引擎模型应如何反射从正面入射的光; 它存储在法线贴图的蓝色通道中。 由于大多数对象从正面照亮时会显示白色,因此法线贴图通常显示为蓝色。
当我们将所有三个图像合为一张时,我们得到一个法线贴图。 请记住,这种解释并不完全正确,但是我希望它能使您理解法线贴图内存储的信息并更好地理解其作用。
总结一下:
法线是用于确定光如何从表面反射的向量。 它们可用于控制面之间的过渡(平均连接的顶点的法线以创建平滑的过渡,或将它们分离以创建刚性的过渡),但是您也可以更改其方向,以使lowpoly模型以与更复杂的模型相同的方式反射光。
该信息存储在三个单独的图像通道中,然后3D编辑器将其读取以了解模型表面应朝哪个方向看。
在本系列的下一篇文章中,我们将讨论如何将这些部分从highpoly模型转变为lowpoly。