法线贴图如何真正起作用?


10

我试图理解法线贴图的概念,但是我对一些事情感到困惑。简而言之,我不确定法线贴图是否依赖于视点(即,围绕同一对象旋转时是否会得到同一对象的不同法线贴图)。其次,我不明白为什么蓝色是法线贴图中的主要颜色

我如何看待法线及其与RGB颜色的关系,如下所示。单位球体表示任何可能的单位法线-换句话说,单位法向向量的X,Y和Z分量的范围是-1至1。RGB颜色的分量的范围都是0至255。因此,这很有意义将-1(标准分量)映射到0(颜色分量),0到127或128以及1到255。介于两者之间的任何值都只是线性插值。

将此映射应用于任意3D对象的法线会产生非常彩色的图像,而根本不是蓝色。例如,当取一个立方体时,所有六个面将具有不同但均匀的颜色。例如,法线为(1,0,0)的脸将为(255,128,128),法线为(0,0,-1)的脸将为(128,128,0),依此类推。

但是,由于某种原因,我找到的多维数据集的法线贴图完全是蓝色的,即(128,128,255)。但很明显,法线并非全部在正z方向上,即(0,0,1)。这是如何运作的?

[编辑]

好的,因此上述方法似乎被称为对象空间法线贴图世界空间法线贴图。另一个称为切线法线贴图。我了解如何使用这种切线空间法线贴图来修改几何体的法线,但是我仍然不确定完全如何计算它(请参阅我在Nicol Bolas的回答中的评论)。

[编辑2]

我可能应该提到我正在处理分段参数化曲面。这些表面由一组表面补丁组成,其中每个补丁都与其自己的参数空间(u,v)= [0,1] x [0,1]相关联。可以在表面的任何一点上精确计算法线。显然,跨越切线空间所需的向量T(切线)和B(双切线)不仅仅是在u和v方向上​​表面补丁的偏导数。


您是否曾经尝试实施phong或至少是漫反射着色?您是否知道单位矢量a,b的基本公式,例如dot(a,b)= cos(angle(a,b))?实施几个小时可以节省您数年的苦恼。
Ivan Kuckir 2013年

@Ailurus:有关如何处理地形对象/高度字段的相同问题,请参阅我的评论/答案。对于其他对象,确实有些复杂,但是概念应该没有什么不同。
teodron

Answers:


14

纹理映射是3D表面上的点与纹理图像上它们的相应点之间的映射。如果您具有1:1的纹理贴图,则3D曲面上的每个点都将映射到纹理图像中的特定且唯一的点(尽管反之不必如此。纹理中的某些位置不一定会映射到该位置在表面上)。

使用这样的贴图,您可以遍历3D表面并将每个不同的法线存储在纹理的相应位置。

好吧,让我们这样做。我们将遍历3D表面,并生成映射位置的对象空间法线,然后将其粘贴在纹理中。因此,当我们要渲染时,我们只需从纹理获取对象空间法线就可以了。对?

好吧,那会起作用。但这也意味着纹理的法线只能与该特定对象一起使用。这也意味着纹理的法线只能与该对象以及特定的纹理映射一起使用。因此,如果您想以某种方式旋转纹理贴图,或者通过一些UV变换对其进行更改,那么您将失去运气。

因此,通常,人们使用的是法线贴图,其中法线位于“切线空间”中。切线空间是相对于3D曲面上的映射点的空间,未修改的法线在+ Z方向上,X和Y轴相对于该曲面沿U和V轴指向。

切线空间实质上使法线正规化。在切线空间中,法线(0,0,1)始终表示“未修改”。这是从顶点法线插值得到的法线。这带来了许多您可以做的有用的事情,其中最重要的事情之一就是将它们存储在更少的数据中。

由于Z始终为正,因此您可以在着色器中根据X和Y分量对其进行计算。由于您仅需要2个值,因此您可以使用(在OpenGL图像格式命名法中GL_RG82个字节/像素的格式,而不是GL_RGBA84个字节/像素(GL_RGB8仍为4个字节/像素) ,因为GPU会将每个像素填充到4个字节)。更好的是,您可以压缩这两个值,从而得到每像素1字节的格式。因此,您已经将纹理的大小减小到了对象空间法线贴图的75%。

在讨论任何类型的法线贴图之前,您需要首先知道其存储的内容。它是对象空间法线贴图,切线空间法线贴图还是其他东西?


好吧,所以您描述的第一种地图类型是对象空间法线映射,对吗?这是更彩色的,因为它存储了法线的真实X,Y和Z分量。第二种类型是切线空间法线贴图,似乎存储的是法线的扰动,而不是法线本身。我将继续学习切线空间的概念,然后再进行检查。
Ailurus

好的,所以表面上一点的切线空间就是该点所有切线向量的空间。但是,在那种情况下,我看不到从切线空间看到的法线除了(0,0,1)以外还不能是其他任何东西?换句话说,我总是希望法线贴图统一为蓝色(128,128,255)。但是,维基百科页面(en.wikipedia.org/wiki/Normal_mapping#How_it_works)上显示的示例包含其他颜色。我确实了解如何使用此贴图来更改法线,但不能真正地计算它。
Ailurus

@Ailurus:“ 好吧,所以表面上一点的切线空间就是该点所有切线向量的空间。 ”不,不是。它是由(未修改的)法线和表面上该点处的纹理坐标方向定义的空间。它将存储在纹理中的法线相对于纹理映射和修改前的当前法线进行规范化。
Nicol Bolas 2013年

关于法线贴图,最困难的部分可能是贴图本身(包括如何计算切向​​量)。切向量的计算是否固有地与漫反射纹理的UV映射/包装以及对象的几何形状固有地联系在一起?换句话说,您有一个对象有两个不同的法线贴图,但是只计算了一个切线(和法线)字段。您可能会发现无法将切线场与两个不同的法线纹理一致地使用(尽管在几何上,您可以找到合适的uv贴图,这并非易事)。
teodron

@NicolBolas啊,我很困惑,因为有些资料声称向量T,B和N构成正交基础,而另一些人提到这不一定是正确的。
Ailurus

3

法线贴图是使用所谓的切线空间进行映射的,该切线空间实际上是基于模型的纹理空间的局部空间。这应该回答您的两个问题。

它与视点无关,因为该空间与相机无关。在法线贴图中,Z是向上方向。如果查看模型的法线,则大多数法线矢量将直接从网格中指向。网格的表面是我所讨论的纹理空间,因此在该局部坐标系中,向上是“向外”方向。


感谢您澄清这一点!但是,我不是使用多边形网格作为曲面,而是使用分段平滑的参数化曲面。因此,所有法线都将保存为指向(0,0,1)方向,对吗?
Ailurus

1

在此页面中向下滚动

查看数据集下的右侧B / W图-这是(或至少以前被称为)刺猬图,是绘制每个法线的表面的渲染

因此,要了解传统的法线贴图,请考虑刺痛的刺猬,它们的所有刺都伸出来-这些刺中的每一个都垂直于刺猬下面的刺猬-

关于球体问题,如果您像射线追踪器那样纯粹生活在参数空间中,则球体的无穷法线集将简单地创建一个更大的球体-在细分空间中,即计算机向我们施加的力我们需要实时,那么您将得到一个球面的尖峰近似。

现在,该示例着重于一个对象法线贴图-它定义了相对于对象的法线,并且在对象,摄像机或其他任何物体的任何旋转,平移或缩放下均不变-如前所述,这是只有一种法线贴图,但是最常见


0

我想您可能对法线贴图有一些误解。基本上,这是一种模拟实际上凹凸不平的外观(实际上是完全平坦的几何形状)的方式。

法线贴图的颜色由技术着色器解释,并根据光强度和方向以及您的相机视图进行处理。例如,这意味着您可以拥有一个完全平坦的砖地板,具有平坦的纹理,但是由于它具有具有相同砖形状的法线贴图,因此当您环顾四周时,光线似乎会从侧面反弹的砖块使它看起来比3D更加真实。

这当然只是一种错觉,但比具有复杂的几何图形便宜得多。不,法线贴图的颜色不会改变。它们实际上只是代表要与着色器进行比较的值。我相信这里有人可以为您提供更多详细信息。


我知道,但是仍然感谢您的回答:)
Ailurus 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.