feat: barycentric interpolation for normals

This commit is contained in:
2025-11-22 12:08:18 +01:00
parent 9a8b1fb5c1
commit 0c94bf1df2
3 changed files with 83 additions and 7 deletions

View File

@@ -7,8 +7,10 @@ struct polygon {
vec3 points[3];
decimal delta[9];
bool small = false;
decimal baryFactor;
decimal bounding[4]; // min x, max x, min y, max y
vec3 normals[3];
polygon(const vec3 &v1, const vec3 &v2, const vec3 &v3)
: points{v1, v2, v3}, delta{} {}
@@ -40,6 +42,16 @@ struct polygon {
if (bounding[3] < points[i].y())
bounding[3] = points[i].y();
}
baryFactor =
(points[1].x() - points[0].x()) * (points[2].y() - points[1].y()) -
(points[1].y() - points[0].y()) * (points[2].x() - points[1].x());
if (baryFactor.isSmall()) {
small = true;
} else
baryFactor = decimal(1.0) / baryFactor;
// std::cout << baryFactor << std::endl;
/*if ((bounding[1].i - bounding[0].i < 1 << HALF_SHIFT) &&
(bounding[3].i - bounding[2].i < 1 << HALF_SHIFT))
small = true;*/
@@ -53,7 +65,7 @@ struct polygon {
return true;
vec3 d = p;
if ((d.x() * delta[i * 3] + d.y() * delta[i * 3 + 1] +
delta[i * 3 + 2]) > decimal(0))
delta[i * 3 + 2]) > decimal(0.2))
return false;
}
return true;
@@ -64,6 +76,32 @@ struct polygon {
}
return os;
}
vec3 calcNormal(vec3 barycentrics) {
vec3 result = normals[0] * barycentrics[0] +
normals[1] * barycentrics[1] +
normals[2] * barycentrics[2];
return result.normalize();
}
decimal calcDepth(vec3 barycentrics) {
return points[0].z() * barycentrics[0] +
points[1].z() * barycentrics[1] +
points[2].z() * barycentrics[2];
}
vec3 calcBarycentric(vec3 s) {
if (small)
return vec3(decimal(0.333), decimal(0.333), decimal(0.333));
vec3 result;
result[0] = (points[1].x() - s.x()) * (points[2].y() - s.y()) -
(points[2].x() - s.x()) * (points[1].y() - s.y());
result[1] = (points[2].x() - s.x()) * (points[0].y() - s.y()) -
(points[0].x() - s.x()) * (points[2].y() - s.y());
result = result * baryFactor;
result[2] = decimal(1.0) - result[1] - result[0];
return result;
}
};
#endif