Я знаю, что об этом тихо спрашивали несколько раз, но моя проблема не в том, как это сделать. Я знаю, как это работает (или, по крайней мере, я так думаю ^^), но что-то не так с моей реализацией, и я не могу отстать от этого.
У меня есть процедурно сгенерированная сетка 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());
Задача ещё не решена.
Других решений пока нет …