我知道这已经被问过几次了,但我的问题不在于如何去做。我知道这是如何工作的(或者至少我是这么认为的^^),但我的实现似乎有问题,我无法支持它。我有一个程序生成的地形网格,我试图通过平均这个顶点连接到的所有三角形的法线来计算每个顶点的法线。当将法线 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());