Replace the average normal with angle and area weighted normal

See details here: http://www.bytehazard.com/articles/vertnorm.html
master
Jeremy Hu 2018-10-19 07:57:39 +08:00
parent 328f26429b
commit 2f32158940
2 changed files with 25 additions and 1 deletions

View File

@ -1065,3 +1065,8 @@ https://www.reddit.com/r/gamedev/comments/5iuf3h/i_am_writting_a_3d_monster_mode
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
</pre> </pre>
<h1>Martijn Buijs</h1>
<pre>
http://www.bytehazard.com/articles/wnormals100.ms
</pre>

View File

@ -420,11 +420,30 @@ void MeshResultContext::calculateResultTriangleUvs(std::vector<ResultTriangleUv>
void MeshResultContext::interpolateVertexNormals(std::vector<QVector3D> &resultNormals) void MeshResultContext::interpolateVertexNormals(std::vector<QVector3D> &resultNormals)
{ {
resultNormals.resize(vertices.size()); resultNormals.resize(vertices.size());
auto angleBetweenVectors = [](const QVector3D &first, const QVector3D &second) {
return std::acos(QVector3D::dotProduct(first.normalized(), second.normalized()));
};
auto areaOfTriangle = [](const QVector3D &a, const QVector3D &b, const QVector3D &c) {
auto ab = b - a;
auto ac = c - a;
return 0.5 * QVector3D::crossProduct(ab, ac).length();
};
for (size_t triangleIndex = 0; triangleIndex < triangles.size(); triangleIndex++) { for (size_t triangleIndex = 0; triangleIndex < triangles.size(); triangleIndex++) {
const auto &sourceTriangle = triangles[triangleIndex]; const auto &sourceTriangle = triangles[triangleIndex];
const auto &v1 = vertices[sourceTriangle.indicies[0]].position;
const auto &v2 = vertices[sourceTriangle.indicies[1]].position;
const auto &v3 = vertices[sourceTriangle.indicies[2]].position;
float area = areaOfTriangle(v1, v2, v3);
float angles[] = {angleBetweenVectors(v2-v1, v3-v1),
angleBetweenVectors(v1-v2, v3-v2),
angleBetweenVectors(v1-v3, v2-v3)};
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
resultNormals[sourceTriangle.indicies[i]] += sourceTriangle.normal; resultNormals[sourceTriangle.indicies[i]] += sourceTriangle.normal * area * angles[i];
} }
for (auto &item: resultNormals) for (auto &item: resultNormals)
item.normalize(); item.normalize();
} }