我正在尝试从网格的细分计算法线贴图,有2个网格包含四边形和三角形的UV展开基础网格和仅包含四边形的细分网格。
假设我有一个四边形,其顶点的所有坐标都在物体空间和UV空间中(四边形不平坦),四边形的面法线和一个像素在UV空间中的位置。
我可以计算给定四边形的TBN矩阵并将颜色写入像素,如果是,那么它对于四边形是不同的吗?
我问这个是因为我找不到任何计算四边形的TBN矩阵的例子,只有三角形?
答案 0 :(得分:3)
在回答你的问题之前,让我首先解释一下你实际需要的切线和位数。
让我们忘记一分钟的三角形,四边形或多边形。我们只有一个表面(以任何表示形式给出)和一个纹理坐标形式的参数化,这些参数化是在表面上的每个点定义的。然后我们可以将表面定义为:xyz = s(uv)
。 uv
是一些2D纹理坐标,函数s
将这些纹理坐标转换为3D世界位置xyz
。现在,切线是u坐标增加的方向。即,它是相对于u坐标的3D位置的导数:T = d s(uv) / du
。类似地,比特是相对于v坐标的导数。法线是一个垂直于它们的向量,通常指向外侧。请记住,三个向量通常在表面上的每个点都不同。
现在让我们转到离散的计算机图形,我们用多边形网格逼近连续曲面s
。问题是没有办法再获得精确的切线和bitangents了。我们在离散近似中丢失了很多信息。因此,无论如何我们可以通过三种常见的方式来近似切线:
让我们专注于第三种方法。对于三角形,这尤其简单,因为纹理坐标在三角形上线性插值(重心插值)。因此,导数都是常数(它只是一个线性函数)。这就是为什么你可以计算每个三角形的切线/比特数。
对于四边形,这不是那么简单。首先,您必须就从四边形的顶点到其内部插入位置和纹理坐标的方法达成一致。通常,使用双线性插值。然而,这不是线性插值,即切线和比特数不再是常数。这只会在特殊情况下发生(如果四边形是平面的,并且uv空间中的四边形是平行四边形)。一般来说,这些假设并不成立,你最终会得到四边形上每个点的不同切线/比特数/法线。
计算所需导数的一种方法是引入辅助坐标系。让我们定义一个坐标系st
,其中四边形的第一个角有坐标(0, 0)
,对角线对角有(1, 1)
(其他角有(0, 1)
和(1, 0)
)。这些实际上是我们的插值坐标。因此,给定任意插值方案,计算导数d xyz / d st
和d uv / d st
相对简单。第一个将是3x2矩阵,第二个将是2x2矩阵(这些矩阵称为插值的雅可比矩阵)。然后,给定这些矩阵,您可以计算:
d xyz / d uv = (d xyz / d st) * (d st / d uv) = (d xyz / d st) * (d uv / d st)^-1
这将为您提供一个3x2矩阵,其中第一列是切线,第二列是比特。