我已经在网上看了很长时间,但无法找到答案。 为简单起见,我们假设我需要完全平滑一组连接面的法线。 我想找到一组矢量之间的实际几何平分线,忽略重复法线并保持三角汤的准确性。基本上,它需要:
我似乎发现正常平滑的最常见公式是,通过将法线向量相加并除以3来简单地平均它们;例如:
normalize((A + B + C) / 3);
当然除以三是没用的,这已经表示人们提出的天真的,非常头顶的蛮力平均方法的氛围;这个问题也是因为它甚至会使三角汤和平行法线混乱。
我似乎发现的另一个评论是保留最初的" facet"它们来自生成它们的常见交叉乘法运算,因为它们(有点)对三角形区域进行加权。这可能是你想要在某些情况下做的事情,但是我需要纯粹的平分线,所以区域不能影响公式,甚至考虑它仍然会被三角形汤弄乱。
我看到一种提到的方法是说要对相邻面之间的角度进行加权,但我似乎无法正确实施公式 - 要么就是这样做,要么就是没有做我想做的事情。然而,这对我来说很难说,因为我无法找到一个简明的解释,而且我的思绪因所有这些浪费的头脑风暴而变得麻木。
有人知道一般的公式吗? 如果有任何帮助,我会使用C ++和DirectX11。
编辑:这里有一些类似的问题描述了一些方法;
另外这篇文章: http://www.bytehazard.com/articles/vertnorm.html
不幸的是,我尝试的实现并没有起作用,我无法找到一个清晰,简洁的声明,说明哪个公式实际上是我需要的公式。经过一些反复试验后,我终于发现按角度加权是正确的方法,只有我无法正确实现;因为它现在似乎正在工作,我将在下面添加我的实现作为答案。
答案 0 :(得分:3)
正确的方法是对" facet"法线对着边/角中共享的两个相邻顶点之间的角度。
以下是示例实现的概要:
for (int f = 0; f < tricount; f++)
{
// ...
// p1, p2 and p3 are the points in the face (f)
// calculate facet normal of the triangle using cross product;
// both components are "normalized" against a common point chosen as the base
float3 n = (p2 - p1).Cross(p3 - p1); // p1 is the 'base' here
// get the angle between the two other points for each point;
// the starting point will be the 'base' and the two adjacent points will be normalized against it
a1 = (p2 - p1).Angle(p3 - p1); // p1 is the 'base' here
a2 = (p3 - p2).Angle(p1 - p2); // p2 is the 'base' here
a3 = (p1 - p3).Angle(p2 - p3); // p3 is the 'base' here
// normalize the initial facet normals if you want to ignore surface area
if (!area_weighting)
{
normalize(n);
}
// store the weighted normal in an structured array
v1.wnormals.push_back(n * a1);
v2.wnormals.push_back(n * a2);
v3.wnormals.push_back(n * a3);
}
for (int v = 0; v < vertcount; v++)
{
float3 N;
// run through the normals in each vertex's array and interpolate them
// vertex(v) here fetches the data of the vertex at index 'v'
for (int n = 0; n < vertex(v).wnormals.size(); v++)
{
N += vertex(v).wnormals.at(n);
}
// normalize the final normal
normalize(N);
}
这是一个天真&#34;的例子。法线的平均值(即没有角度加权);
您可以看到构面组件完全相同,但由于某些边有两个面,因此它们的插值部分加倍,使得平均值偏斜。仅对表面区域进行加权,而不是对角度进行加权,会产生类似的结果。
这是相同的模型,但启用了角度加权;
现在插值法线在几何上都是正确的。