如何在 Vulkan 中计算三角形是后向还是正面

How to calculate if a triangle is back-facing or front facing in Vulkan

提问人:Owen Zhang 提问时间:11/12/2023 最后编辑:Owen Zhang 更新时间:11/13/2023 访问量:42

问:

本页内容: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkFrontFace.html 他们给出了这个等式:enter image description here

例如,您将如何将该公式应用于具有这些坐标的三角形?

p0(-0.5, -0.5)

p1(0.5, -0.5)

p2(0.5, 0.5)

它会扩展到这样的东西吗?

(-1/2)( ((p0.x)(p1.y) - (p1.x)(p0.y)) + ((p1.x)(p2.y) - (p2.x)(p1.y)) + ((p2.x)(p0.y) - (p0.x)(p2.y)) )

(-1/2)( ((-0.5)(-0.5) - (0.5)(-0.5)) + ((0.5)(0.5) - (0.5)(-0.5)) + ((0.5)(-0.5) - (-0.5)(0.5)) )

(-1/2)( (0.5) + (0.5) + (0.0) )

-0.5

符号是负的,所以它是正面的,因为“具有负面积的三角形被认为是正面的。

如果是这样,这如何与正态计算相对应?

vulkan 矢量图形

评论


答:

1赞 krOoze 11/13/2023 #1

三角形似乎是这样的:

triangle with winding

绕组似乎是顺时针方向的,因此在默认值(逆时针)下,它将是背面的。

这个公式不是 Vulkan 发明的。它是三角形面积的基本公式。经典形式是这样的:0.5|AB×AC|ABC 是按此指定顺序排列的顶点,因此 ABAC 是线段\向量:

enter image description here

就我们的目的而言,我们并不完全需要面积,我们只需要法线的方向。它们恰好几乎是一回事。我们通过计算叉积得到一个正态值:AB×AC。这产生了向量
(0, 0, AB.x⋅AC.y - AB.y⋅AC.x)。

只有一个分量的向量的大小是它的绝对值。我们跳过绝对值操作,以获得一个有符号的“区域”。所以我们只有:
AB.x⋅AC.y - AB.y⋅AC.x

AB 只是 B-A,类似 AC = C-A,因此代入它并处理乘法,得到:
Ax⋅By-Bx⋅Ay + Bx⋅Cy-Cx⋅By + Cx⋅Ay-Ax⋅Cy
这与规范中的 Σ 匹配。

根据你的数字,得出 (-0.5⋅-0.5)-(0.5⋅-0.5) + (0.5⋅0.5)-(0.5⋅-0.5) + (0.5⋅-0.5)-(-0.5⋅0.5) = 1

1/2 乘法显然对我们来说无关紧要,因为它不会改变符号。但无论如何,这使得它成为 1/2×1 = 0.5。这检查了:1x1 直角三角形的面积 0.5。

向下摆动的 y 坐标会导致镜像,因此会改变绕组的感知方向:

enter image description here

因此,我们必须交换等式中的符号:-0.5(AB.x⋅AC.y - AB.y⋅AC.x)。所以我们得到 -0.5。

在 的情况下,正面是具有正区域的正面,因此我们确实看到了背面。VK_FRONT_FACE_COUNTER_CLOCKWISE

评论

0赞 Owen Zhang 11/15/2023
感谢您的回答,对于这部分:“y 坐标向下倾斜会导致镜像,因此会改变绕组的感知方向”这是什么意思?
0赞 krOoze 11/15/2023
@OwenZhang 比较答案中的第二张和第三张图片。看蜿蜒箭头的方向。这就是为什么与传统方程相比,方程具有减号的原因。通常,传统的数学从+Z看事物,右手图形(通常Y朝下)从-Z看。它改变了我们认为的“前线”,因为我们是从另一个方向看的。
0赞 Jherico 11/19/2023
我不会仅仅因为逆时针方向等于零VK_FRONT_FACE_COUNTER_CLOCKWISE就将逆时针称为“默认值”。我想,如果您将光栅化结构初始化为全零并且不填充变量,那么它将成为默认值,但这似乎是不好的做法。
1赞 krOoze 11/20/2023
@Jherico 还有其他原因。它是 OpenGL 中的默认约定,因为它是一般的默认约定(又名右手规则)。