From bbc95a136438fd22fb3c312f8e0f74e5443a0868 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Tue, 5 Apr 2016 15:00:12 -0600 Subject: [PATCH] light: phong shading: also weight by face area. this avoids cubes with rounded edges turning completely into blobs --- light/light.cc | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/light/light.cc b/light/light.cc index 83a75756..29fe6034 100644 --- a/light/light.cc +++ b/light/light.cc @@ -331,6 +331,17 @@ AngleBetweenPoints(const vec3_t p1, const vec3_t p2, const vec3_t p3) return result; } +static vec_t +TriangleArea(const vec3_t v0, const vec3_t v1, const vec3_t v2) +{ + vec3_t edge0, edge1, cross; + VectorSubtract(v2, v0, edge0); + VectorSubtract(v1, v0, edge1); + CrossProduct(edge0, edge1, cross); + + return VectorLength(cross) * 0.5; +} + class vec3_struct_t { public: vec3_t v; @@ -350,14 +361,15 @@ AddTriangleNormals(std::map &smoothed_normals, const vec_t * const vec_t *p2 = verts[v2].point; const vec_t *p3 = verts[v3].point; float weight; + float area = TriangleArea(p1, p2, p3); - weight = AngleBetweenPoints(p2, p1, p3); + weight = AngleBetweenPoints(p2, p1, p3) * area; VectorMA(smoothed_normals[v1].v, weight, norm, smoothed_normals[v1].v); - weight = AngleBetweenPoints(p1, p2, p3); + weight = AngleBetweenPoints(p1, p2, p3) * area; VectorMA(smoothed_normals[v2].v, weight, norm, smoothed_normals[v2].v); - weight = AngleBetweenPoints(p1, p3, p2); + weight = AngleBetweenPoints(p1, p3, p2) * area; VectorMA(smoothed_normals[v3].v, weight, norm, smoothed_normals[v3].v); } /* small helper that just retrieves the correct vertex from face->surfedge->edge lookups */