I have a obj file which stores data this way:
v value1 value2 value3
f value1 value2 value3
First I calculate a normal for the face and then assign for each vertex of that face:
for(int i = 0; i < verticesInd.size(); i+=3)
{
glm::vec3 normal = glm::normalize(glm::cross(glm::vec3(vertices[verticesInd[i + 1]]) - glm::vec3(vertices[verticesInd[i]]), glm::vec3(vertices[verticesInd[i + 2]]) - glm::vec3(vertices[verticesInd[i]])));
out_Normals[i] = normal;
out_Normals[i + 1] = normal;
out_Normals[i + 2] = normal;
}
For achieve a flat shading I can duplicate vertices:
for(int i = 0; i < verticesInd.size(); i++)
{
out_Vertices.push_back(vertices[verticesInd[i]]);
}
and then draw the object using glDrawArrays:
glDrawArrays(GL_TRIANGLES, 0, out_Vertices.size());
For achieve a smooth shading I need to average normals for each vertex but I have no idea how to find adjacent faces.
Edit1: I didn’t notice a single s parameter before f:
v value1 value2 value3
s 1
f value1 value2 value3
Edit2: Normals averaging
glm::vec3 tNormal;
for(int i = 0; i < vertices.size(); i++)
{
for(int j = 0; j < verticesInd.size(); j++)
{
if(verticesInd[j] == i)
{
tNormal += faceNormals[j / 3];
}
}
aNormals.push_back(glm::normalize(tNormal));
tNormal = glm::vec3(0,0,0);
}
Edit 3 Face normals:
for(int i = 0; i < verticesInd.size(); i+=3)
{
glm::vec3 normal = glm::normalize(glm::cross(glm::vec3(vertices[verticesInd[i + 1]]) - glm::vec3(vertices[verticesInd[i]]), glm::vec3(vertices[verticesInd[i + 2]]) - glm::vec3(vertices[verticesInd[i]])));
faceNormals.push_back(normal);
}
In most object formats adjacent faces should be sharing vertices. Finding the smooth shaded normal at a vertex should just then be a question of averaging the normal of any face which uses that vertex.
I suggest that you create an additional new array the same size as your existing vertex array.
Iterate over each face, and for each vertex index, add that vertice’s face normal to the new array.
At the end of the process, normalise the result normal vectors and then use that instead of the previously computed face normals.
If I understand your data structures correctly, it would look something like this: