Shaders: How to deal with sharp corners / edges in the model



Sooo…anyone got any tips on how to fix this ugliness?

I’m Using panda3d 1.9.4 with custom GLSL shaders. The shader basically has ambient and directional light that interacts with the normals of the surface for directionally based specularity and diffuse interactions and all.

My shader doesn’t handle the sharp edge at the bottom very well. The reason is that I am calculating the normals using vertex positions and the triangles: For each vertex, I look at all connected triangles, and sum their area vectors and then normalize, and thats the normal value for the vertex.

The bottom flat surface has one vertex in the middle, with triangles fanning out around it to connect to the edge. As a result, the normals of those triangles are really large and thus skewing the normals at the bottom edge, which interferes with shader lighting effects.

Now, one way to fix this is to keep track of which vertex is responsible for the flat part, and when computing normals, set those faces connected to that to have zero normal values, and the bottom flat looks dark but the edge looks much better.

The problem with that is I have to constantly update the normals as the geometry is modified during program run, and that will reorder all the vertices in some cases. And if I save as OBJ or STL file and reload, then I’ll get the original normals but when I need to recompute, the record of which face is at the bottom is lost. It would be possible to keep track of all this, but I think its starting to look kinda messy.

Another option is to use not just one vertex at the flat spot, but have multiple vertices going out from center and figuring out how to connect them with triangles appropriately (using procedurally generated Geoms and all).

Thats probably my best bet so far, but even that is not ideal, since the normals at the edge would be skewed downward a bit, but not as much.

Are there any other ideas on how to deal with this? Do note that the shape above the edge is gonna be somewhat irregular and the mesh isn’t going to be repeating necessarily.

I have managed to fix this manually by setting the normals of the faces at the flat to zero, but otherwise telling it to ignore those faces when computing normals at the edges hasn’t worked, which leads me to think that there’s something going on with the shaders interpolation settings or whatnot.

The typical way to deal with this is to set a maximum angle; when calculating normals for a vertex, you take the dot product of adjacent face normals and don’t consider them if they make an angle of more than, say, 30°.

Another way to do it is just to keep the mesh parts for the bottom and the side separate, ie. have two sets of vertices on the bottom ring, one used for the cap and the other for the tube. This is probably an easier approach if you have control over the geometry generation.