title: General method for calculating Smooth vertex normals with 100% smoothness
body: <p>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. <strong>I want to find the actual geometric bisector between a group of vectors, ignoring duplicate normals and maintaining accuracy with triangle soups</strong>. Basically, it needs to:</p>
  
  <ul>
  <li>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</li>
  <li>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</li>
  </ul>
  
  <p>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:</p>
  
  <pre><code>normalize((A + B + C) / 3);
  </code></pre>
  
  <p>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.</p>
  
  <p>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.</p>
  
  <p>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.</p>
  
  <p>Anybody knows of a general formula?
  If it is of any help, I'm working with C++ and DirectX11.</p>
  
  <hr>
  
  <p><strong>Edit</strong>: Here's some similar questions that describe some of the methods;</p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/21766605/how-to-achieve-smooth-tangent-space-normals">How to achieve smooth tangent space normals?</a></li>
  <li><a href="https://stackoverflow.com/questions/16340931/calculating-vertex-normals-of-a-mesh">Calculating Vertex Normals of a mesh</a></li>
  <li><a href="https://stackoverflow.com/questions/6656358/calculating-normals-in-a-triangle-mesh">Calculating normals in a triangle mesh</a></li>
  <li><a href="https://stackoverflow.com/questions/25100120/how-does-blender-calculate-vertex-normals">How does Blender calculate vertex normals?</a></li>
  <li><a href="https://stackoverflow.com/questions/13205226/most-efficient-algorithm-to-calculate-vertex-normals-from-set-of-triangles-for-g">Most efficient algorithm to calculate vertex normals from set of triangles for Gouraud shading</a></li>
  </ul>
  
  <p>Also this article:
  <a href="http://www.bytehazard.com/articles/vertnorm.html" rel="noreferrer">http://www.bytehazard.com/articles/vertnorm.html</a></p>
  
  <p>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.</p>