C++ 三角形和四边形计算TBN矩阵的差异?

C++ 三角形和四边形计算TBN矩阵的差异?,c++,opengl,graphics,3d,geometry,C++,Opengl,Graphics,3d,Geometry,我试图从网格的细分计算法线贴图,有两个网格一个是包含四边形和三角形的UV展开基础网格,另一个是仅包含四边形的细分网格 假设我有一个四边形,其中包含对象空间和UV空间中顶点的所有坐标(四边形不是平面),四边形的面法线和一个像素及其在UV空间中的位置 我可以计算给定四元体的TBN矩阵并将颜色写入像素吗?如果可以,那么四元体的TBN矩阵是否不同 我问这个问题是因为我找不到任何例子来计算四边形的TBN矩阵,只有三角形?在回答你的问题之前,让我先解释一下你需要的切线和双切线是什么 让我们暂时忘记三角形、四

我试图从网格的细分计算法线贴图,有两个网格一个是包含四边形和三角形的UV展开基础网格,另一个是仅包含四边形的细分网格

假设我有一个四边形,其中包含对象空间和UV空间中顶点的所有坐标(四边形不是平面),四边形的面法线和一个像素及其在UV空间中的位置

我可以计算给定四元体的TBN矩阵并将颜色写入像素吗?如果可以,那么四元体的TBN矩阵是否不同


我问这个问题是因为我找不到任何例子来计算四边形的TBN矩阵,只有三角形?

在回答你的问题之前,让我先解释一下你需要的切线和双切线是什么

让我们暂时忘记三角形、四边形或多边形。我们只有一个曲面(以任何表示形式给出)和一个纹理坐标形式的参数化,这些坐标在曲面上的每个点上定义。然后我们可以将曲面定义为:
xyz=s(uv)
uv
是一些2D纹理坐标,函数
s
将这些纹理坐标转换为3D世界位置
xyz
。现在,切线是u坐标增加的方向。即,它是3D位置相对于u坐标的导数:
T=ds(uv)/du
。类似地,双切线是相对于v坐标的导数。法线是一个垂直于两者的向量,通常指向外部。请记住,这三个向量通常在曲面上的每个点都不同

现在让我们转到离散计算机图形学,在这里我们用多边形网格近似连续曲面
s
。问题是没有办法再得到精确的切线和双切线了。我们在离散近似中丢失了很多信息。因此,我们有三种常用的方法来近似切线:

  • 将向量与模型一起存储(通常不这样做)
  • 估计顶点处的向量并在面中对其进行插值
  • 分别计算每个面的向量。这将为您提供一个不连续的切线空间,当两个相邻面之间的二面角过大时,会产生瑕疵。不过,这显然是大多数人正在做的事情。这显然也是你想要做的
  • 让我们关注第三种方法。对于三角形,这尤其简单,因为纹理坐标是跨三角形线性插值的(重心插值)。因此,导数都是常数(它只是一个线性函数)。这就是为什么可以计算每个三角形的切线/双切线

    对于四边形,这并不是那么简单。首先,必须就从四边形顶点到其内部的位置和纹理坐标插值方法达成一致。通常使用双线性插值。但是,这不是线性插值,即切线和双切线不再是常数。这只会在特殊情况下发生(如果四边形是平面的,并且uv空间中的四边形是平行四边形)。通常,这些假设不成立,最终四元体上的每个点都会有不同的切线/双切线/法线

    计算所需导数的一种方法是引入辅助坐标系。让我们定义一个坐标系
    st
    ,其中四边形的第一个角具有坐标
    (0,0)
    ,对角的角具有
    (1,1)
    (其他角具有
    (0,1)
    (1,0)
    )。这些实际上是我们的插值坐标。因此,给定任意插值方案,计算导数
    dxyz/dst
    duv/dst
    相对简单。第一个是3x2矩阵,第二个是2x2矩阵(这些矩阵称为插值的雅可比矩阵)。然后,根据这些矩阵,您可以计算:

    d xyz / d uv = (d xyz / d st) * (d st / d uv) = (d xyz / d st) * (d uv / d st)^-1
    

    这将为您提供一个3x2矩阵,其中第一列为切线,第二列为双切线。

    在回答您的问题之前,让我先解释一下实际需要的切线和双切线是什么

    让我们暂时忘记三角形、四边形或多边形。我们只有一个曲面(以任何表示形式给出)和一个纹理坐标形式的参数化,这些坐标在曲面上的每个点上定义。然后我们可以将曲面定义为:
    xyz=s(uv)
    uv
    是一些2D纹理坐标,函数
    s
    将这些纹理坐标转换为3D世界位置
    xyz
    。现在,切线是u坐标增加的方向。即,它是3D位置相对于u坐标的导数:
    T=ds(uv)/du
    。类似地,双切线是相对于v坐标的导数。法线是一个垂直于两者的向量,通常指向外部。请记住,这三个向量通常在曲面上的每个点都不同

    现在让我们转到离散计算机图形学,在这里我们用多边形网格近似连续曲面
    s
    。问题是没有办法再得到精确的切线和双切线了。我们在离散近似中丢失了很多信息。因此,我们有三种常用的方法来近似切线:

  • 将向量与模型一起存储(通常不这样做)
  • 估计顶点处的向量并在面中对其进行插值
  • 分别计算每个面的向量。这将为您提供一个不连续的切线空间,当两个相邻面之间的二面角过大时,会产生瑕疵。然而,这显然是什么