如何插值顶点法线?

6

我正在尝试使用 marching cubes 算法对来自 volvis.org 的 3D 模型进行 Gouraud 阴影处理。到目前为止,我已经得到了每个顶点的法线:

GetNormalForVertex(vertex &b, vertex &a, vertex &c) {
    u.X = a.X - b.X;
    u.Y = a.Y - b.Y;
    u.Z = a.Z - b.Z;
    v.X = c.X - b.X;
    v.Y = c.Y - b.Y;
    v.Z = c.Z - b.Z;

    return  Cross(u,v);
}

当渲染时,我可以看到一个漂亮的平面阴影。据我所知,为了获得高洛德着色效果,我需要插值这些顶点法线以找到交点处的法线。如何插值顶点法线呢?


你想用着色器实现吗?还是有其他方法? - D-rk
它可以是着色器(更快,对吧?) - Floyd Barber
2个回答

12
首先,你并没有计算顶点法线。你正在计算的是面法线。这是计算顶点法线过程中的第一步。
接下来的步骤不是插值任何东西。你要做的是为每个连接到一个顶点的面计算(未归一化的)面法线。然后将它们全部加在一起并将结果归一化。那就是顶点法线。
如何确定哪些面连接到一个顶点是另一回事。在你的情况下,因为你是通过 marching cubes 构建这个数据,所以生成或检索相邻立方体的三角形应该不太困难。但如果你已经通过了生成步骤,只有一堆三角形,那么你需要一个适当的网格拓扑数据结构。Winged-edgeQuad-edge 都是不错的选择。

好的Nicol,非常感谢你的澄清,我会去处理的。问候! - Floyd Barber

10

a、b和c是什么?

如果它们是三角形的顶点,那么你正在计算三角形的法向量,而不是任何特定顶点的法向量。在这种情况下的假设是整个三角形是平面的。这被称为平面着色

另一方面,如果你希望在三角形内部插值表面法向量(在Gouraud着色中使用),那么你需要一开始就有三个不同的法向量在三个顶点上。这有点棘手,但仍然很容易。一种方法是取所有共享一个顶点的三角形的法向量的平均值以获得该顶点处的法向量。这显然需要连接信息(或者你需要以某种方式提取它)。

一旦你有了三个不同的法向量(例如na,nb,nc),那么通过重心坐标可以计算出任何内部点的法向量。设定顶点为va,vb,vc,内部点的重心坐标为α和β,则内部点v及其法线n由以下公式给出:

v = α*va + β*vb + (1 - α - β)*vc
n = α*na + β*nb + (1 - α - β)*nc

应使用这个插值法算出的法向量 (n) 进行 Gouraud 着色。


是的,a、b和c是三角形的顶点,我使用函数GetNormalForVertex计算每个顶点的法线。如果我有一个三角形结构体数组,如何获取共享的顶点? - Floyd Barber
1
当我写下“这有点不那么琐碎”时,我的意思就是这个。我建议您查看上面@Nicol的答案。 - Rahul Banerjee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接