0
\$\begingroup\$

Im trying to procedurally generate planets for a project I'm working on. By adding noise to each vertex, I'm able to generate elevation, but without having updated vertice normals for my shader. It originally looked something like the picture below.

When I tried to recalculate the vertex normals, I got some ugly sharp lines, most likely as a result from the way I was parsing the model.

shared index vertices?

this is the code Im using to recalculate the normals:

for (auto &x : normals)x = vec3(0);  //zero normals
vec3 facenormal; //buffer

//indices is the faces/triangles indexed, in pairs of 3.
for (size_t i = 0; i<indices.size();) 
{
    facenormal = cross(
        (shape[indices[i + 1]] - shape[indices[i]]), 
        (shape[indices[i + 2]] - shape[indices[i]])
        );

    normals[indices[i++]] += facenormal; 
    normals[indices[i++]] += facenormal; 
    normals[indices[i++]] += facenormal;
}

for (auto &x : normals)x = normalize(x); //normalize adjacent faces

Basically I add up the adjacent faces to the vertices they belong to, then normalize the value they have.

Then, based on suggestions, I took a look at the parsing and made sure it doesnt share vertices in the indexing. This seems to remove the lines, but im still stuck flat shading?

flat shading

But according to this, it should be accurate. So I'm still not fixing the problem. What is the correct formula to do the vertex calculation, if its not what I'm already doing.

using the base mesh, pre indexing, solved the problem!

Like user Kolenda suggests, I was not modifying values at the base-mesh level. but rather, doing them after loading the indexed copies. So, what I end up with is a combination of flat shading faces "shading" ghost vertice normals. Iterating over the faces on a mesh level, with the same formula, solves the problem.

\$\endgroup\$
4
  • \$\begingroup\$ the vertices around a triangle shouldn't have the same normals. What you're doing now is flat shading \$\endgroup\$
    – Bálint
    Mar 16 '17 at 10:30
  • \$\begingroup\$ They dont. Notice +=, and not =, this sum is normalized after, to give the value for each vertice (point). Basically, each point will be the sum of the normals adjacent to it, giving it a smooth curve to pass to the GPU. This is not the problem @Bálint \$\endgroup\$
    – Charlie
    Mar 16 '17 at 10:37
  • 1
    \$\begingroup\$ What method was used to generate the mesh? Are there duplicated vertices along the seams perhaps(which didnt show themselves when the surface was smooth)? \$\endgroup\$
    – wondra
    Mar 16 '17 at 11:17
  • \$\begingroup\$ Your guess is good enough to have me looking for a few hours, but I cant find it yet @wondra \$\endgroup\$
    – Charlie
    Mar 17 '17 at 7:38
1
\$\begingroup\$

You didn't tell us how do you create this mesh but it seems it's made of a few chunks that don't share any vertices. It's similar to the situation when you create a cube with 6 separate sides, then tesselate and normalize those sides separately.

As a result you have visible seams. The normal on one side is an average of triangle normals at that side, but ignores triangles on the other side.

To fix this you could fix the creation of a base sphere mesh - if you have any vertices that have the same position then leave just one of them and remove the rest, updating triangles indices.

\$\endgroup\$
2
  • \$\begingroup\$ Well, I think this is part of the answer, Im parsing in a way that removes duplicate entries, by making the index refer to shared vertices, so, I suspect that it messes with the normal recalculation. But, when I fix this, I get flat shading, see my answer for updates @kolenda \$\endgroup\$
    – Charlie
    Mar 18 '17 at 8:14
  • 1
    \$\begingroup\$ 100% correct :D \$\endgroup\$
    – Charlie
    Mar 19 '17 at 0:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.