我知道这已被问过几次安静,但我的问题不在于如何做到这一点。我知道这是如何工作的(或者至少我认为是这样^^)但是我的实现似乎有些错误,我无法支持它。 我有一个程序生成的Terrain网格,我试图通过平均这个顶点所连接的所有三角形的法线来计算每个顶点的法线。将普通xyz设置为rgb顶点颜色时,似乎它是随机的黑色(0,0,0)或蓝色(0,0,1)。
void CalculateVertexNormal(int index){ //index of the vertex in the mesh's vertex array
std::vector<int> indices; //indices of triangles the vertex is a part of
Vector normals = Vector(0.0f, 0.0f, 0.0f, 0.0f); //sum of all the face normals
for(int i = 0; i < triangles.size(); i += 3){ //iterate over the triangle array in order
if(triangles[i] == index) //to find the triangle indices
indices.push_back(triangles[i]);
else if(triangles[i + 1] == index)
indices.push_back(triangles[i]);
else if(triangles[i + 2] == index)
indices.push_back(triangles[i]);
}
for(int i = 0; i < indices.size(); i++){ //iterate over the indices to calculate the normal for each tri
int vertex = indices[i];
Vector v1 = vertices[vertex + 1].GetLocation() - vertices[vertex].GetLocation(); //p1->p2
Vector v2 = vertices[vertex + 2].GetLocation() - vertices[vertex].GetLocation(); //p1->p3
normals += v1.Cross(v2); //cross product with two edges to receive face normal
}
vertices[index].SetNormals(normals.Normalize()); //normalize the sum of face normals and set to vertex
}
也许有人可以看看并告诉我我做错了什么。 谢谢。
编辑: 感谢molbdnilo的评论,我终于明白了什么是错的。索引数组是一个问题,我的两个循环也有点令人困惑,也许我应该休息一下;) 我最终想出了这个,减少到一个循环:
for(int i = 0; i < triangles.size(); i += 3){
if(triangles[i] == index || triangles[i + 1] == index || triangles[i + 2] == index){
Vector v1 = vertices[triangles[i + 1]].GetLocation() - vertices[index].GetLocation();
Vector v2 = vertices[triangles[i + 2]].GetLocation() - vertices[index].GetLocation();
faceNormals += v1.Cross(v2);
}
}
vertices[index].SetNormals(faceNormals.Normalize());