Fix incorrect signed distance computation in lightmap baking

This commit is contained in:
tovjemam 2025-08-15 19:58:18 +02:00
parent 441503234e
commit 1e089f3918

View File

@ -430,7 +430,12 @@ void game::Sector::GetLightsAt(const glm::vec3& pos, std::vector<Light>& out_lig
static float SignedDistanceToLine(const glm::vec2& p0, const glm::vec2& p1, const glm::vec2& p)
{
// Calculate the signed distance from point p to the line segment p0 -> p1
return (p1.x - p0.x) * (p.y - p0.y) - (p1.y - p0.y) * (p.x - p0.x);
//return (p1.x - p0.x) * (p.y - p0.y) - (p1.y - p0.y) * (p.x - p0.x);
glm::vec2 seg = p1 - p0;
glm::vec2 toPoint = p - p0;
float cross = seg.x * toPoint.y - seg.y * toPoint.x; // signed area * 2
return cross / glm::length(seg); // now in distance units
}
void game::Sector::Bake()
@ -473,9 +478,9 @@ void game::Sector::GenerateAllLights()
void game::Sector::BakeLightmap()
{
const size_t lightmap_size = 512;
const size_t lightmap_size = 128;
const glm::vec3 ambient_light(0.2f); // Ambient light color
const float margin = 2.0f;
const float margin = 1.0f;
std::span<const assets::MeshVertex> mesh_verts = mesh_->GetVertices();
std::span<const assets::MeshTriangle> mesh_tris = mesh_->GetTriangles();
@ -531,11 +536,23 @@ void game::Sector::BakeLightmap()
glm::vec2 texel_pos((float)x + 0.5f, (float)y + 0.5f); // Center of the texel
// Calculate signed distance to the triangle edges
float sd = SignedDistanceToLine(verts[0], verts[1], texel_pos);
sd = glm::min(sd, SignedDistanceToLine(verts[1], verts[2], texel_pos));
sd = glm::min(sd, SignedDistanceToLine(verts[2], verts[0], texel_pos));
float sd0 = SignedDistanceToLine(verts[0], verts[1], texel_pos);
float sd1 = SignedDistanceToLine(verts[1], verts[2], texel_pos);
float sd2 = SignedDistanceToLine(verts[2], verts[0], texel_pos);
if (sd > margin)
float area2 = (verts[1].x - verts[0].x) * (verts[2].y - verts[0].y) -
(verts[1].y - verts[0].y) * (verts[2].x - verts[0].x);
if (area2 < 0.0f) {
// CW winding — flip signs
sd0 = -sd0;
sd1 = -sd1;
sd2 = -sd2;
}
float sd = glm::min(glm::min(sd0, sd1), sd2);
if (sd < -margin)
{
continue; // Texel is outside the triangle even with margin
}