【问题标题】:Differences in calculating TBN matrix for triangles versus quads?计算三角形与四边形的 TBN 矩阵的区别?
【发布时间】:2018-04-21 14:32:48
【问题描述】:

我正在尝试从网格的细分计算法线贴图,有 2 个网格,一个包含四边形和三角形的 UV 展开基础网格,以及一个仅包含四边形的细分网格。

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

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

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

【问题讨论】:

  • 我不确定是否可以为一般四边形计算一致的切线空间。在blender source codedocumentation 中有一点解释,但它们将四边形拆分为三角形进行计算。问题是,必须在整个四边形上插入一致的切线框架,这意味着它必须是连续的。但据我了解,情况并非如此。
  • 为了完整性:现代 OpenGL 不再支持四边形。如果您不是绝对受限于古代版本,请使用三角形网格。
  • 我认为 tbn 是通过使用 2 点之间的 deltaUV 和 deltaPos 求解方程来计算的。对于您的四边形,您有 3 个可用点。我建议避免像搅拌机那样为非平面四边形选择对角的点。
  • 在openGL中,四边形必须是共面的: 四个顶点应该是共面的;不这样做可能会导致不确定的结果。四边形通常被光栅化为一对三角形。这不是 GL 规范定义的,但它是允许的。由于顶点/几何着色器输出在 2 个生成的三角形上的插值方式,这可能会导致一些伪影。 (khronos.org/opengl/wiki/Primitive)
  • 我将使用另一个 3'rd 网格,它是细分网格的三角版本,来计算良好的法线,而不是进行不精确的计算。

标签: c++ opengl graphics 3d geometry


【解决方案1】:

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

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

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

  1. 将向量与模型一起存储(通常不这样做)。
  2. 估计顶点处的向量并将它们插值到面中。
  3. 分别计算每个面的向量。这将为您提供一个不连续的切线空间,当两个相邻面之间的二面角太大时会产生伪影。尽管如此,这显然是大多数人正在做的事情。这显然也是您想要做的。

让我们关注第三种方法。对于三角形,这尤其简单,因为纹理坐标是线性插值(重心插值)跨三角形。因此,导数都是常数(它只是一个线性函数)。这就是为什么您可以计算每个三角形的切线/双切线。

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

计算所需导数的一种方法是引入辅助坐标系。让我们定义一个坐标系st,其中四边形的第一个角坐标为(0, 0),对角坐标为(1, 1)(其他角坐标为(0, 1)(1, 0))。这些实际上是我们的插值坐标。因此,给定任意插值方案,计算导数d xyz / d std 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 矩阵,其中第一列是切线,第二列是双切线。

【讨论】:

    猜你喜欢
    • 2012-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-09
    • 1970-01-01
    • 2019-04-22
    • 2013-03-25
    相关资源
    最近更新 更多