I've looked online for quite some time and can't find an answer to this. For simplicity, let's just assume I need to fully smooth out the normals of a group of cojoined faces. I want to find the actual geometric bisector between a group of vectors, ignoring duplicate normals and maintaining accuracy with triangle soups. Basically, it needs to:
- Work with triangle soups - be it three, 4 or 4000 triangles, the normals still need to work together in a geometrically correct fashion without being biased towards arbitrary areas
- Ignore overlapping (parallel) normals - if I have a cube's edge that comes together in 3 triangles, or one that comes together in one triangle for each of two sides and 2 (or more) for the last side, or one that has a million triangles on only one side, the bisector must not change
The most common formula I seem to be finding for normal smoothing is, to simply average them by summing together the normal vectors and divide by three; example:
normalize((A + B + C) / 3);
Of course dividing by three is useless, which already denotes the vibe of naive, off-the-top-of-your-head brute force averaging method that people propose; problems with this are also the fact that it messes up big time with even triangle soups and parallel normals.
Another remark I seem to find is to keep the initial "facet" normals as they come from a common cross multiply operation that generates them, as that way they are (kinda) weighted against the triangle's area. This might be something you want to do in some cases, however I need the pure bisector, so area must not influence the formula, and even accounting for it it still gets messed up by triangle soups.
I saw one mentioned method that says to weight against the angle between the adjacent faces, but I can't seem to implement the formula correctly - either that or it's not doing what I want. However that's hard for me to say, since I can't find a concise explanation for it and my mind is becoming numb from all this wasted brainstorming.
Anybody knows of a general formula? If it is of any help, I'm working with C++ and DirectX11.
Edit: Here's some similar questions that describe some of the methods;
- How to achieve smooth tangent space normals?
- Calculating Vertex Normals of a mesh
- Calculating normals in a triangle mesh
- How does Blender calculate vertex normals?
- Most efficient algorithm to calculate vertex normals from set of triangles for Gouraud shading
Also this article: http://www.bytehazard.com/articles/vertnorm.html
Unfortunately, the implementations I tried didn't work and I couldn't find a clear, concise statement about which formula was actually the one that I needed. After some trial and error I finally figured out that weighting by angle was the correct way to do it, only I wasn't able to implement it correctly; as it seems to be working now, I'll add my implementation as an answer below.