Fix incorrect signed distance computation in lightmap baking
This commit is contained in:
parent
441503234e
commit
1e089f3918
@ -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)
|
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
|
// 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()
|
void game::Sector::Bake()
|
||||||
@ -473,9 +478,9 @@ void game::Sector::GenerateAllLights()
|
|||||||
|
|
||||||
void game::Sector::BakeLightmap()
|
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 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::MeshVertex> mesh_verts = mesh_->GetVertices();
|
||||||
std::span<const assets::MeshTriangle> mesh_tris = mesh_->GetTriangles();
|
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
|
glm::vec2 texel_pos((float)x + 0.5f, (float)y + 0.5f); // Center of the texel
|
||||||
|
|
||||||
// Calculate signed distance to the triangle edges
|
// Calculate signed distance to the triangle edges
|
||||||
float sd = SignedDistanceToLine(verts[0], verts[1], texel_pos);
|
float sd0 = SignedDistanceToLine(verts[0], verts[1], texel_pos);
|
||||||
sd = glm::min(sd, SignedDistanceToLine(verts[1], verts[2], texel_pos));
|
float sd1 = SignedDistanceToLine(verts[1], verts[2], texel_pos);
|
||||||
sd = glm::min(sd, SignedDistanceToLine(verts[2], verts[0], 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
|
continue; // Texel is outside the triangle even with margin
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user