集成Gutter 边缘缓冲
This commit is contained in:
1 parent
9fb90b00d7
commit
1b9cf3ea46
1 file changed
+57
-3
@@ -14332,6 +14332,8 @@ bool MeshTexture::RasterizeVirtualFaces(
|
||||
// ✅ 拷贝到 atlas(OpenMP critical 区)
|
||||
#pragma omp critical
|
||||
{
|
||||
const int gutter = 4; // 4像素边缘缓冲
|
||||
|
||||
for (int y = 0; y < patchH; ++y) {
|
||||
for (int x = 0; x < patchW; ++x) {
|
||||
cv::Vec3b color = patch.at<cv::Vec3b>(y, x);
|
||||
@@ -14344,6 +14346,56 @@ bool MeshTexture::RasterizeVirtualFaces(
|
||||
atlasY < 0 || atlasY >= textureSize)
|
||||
continue;
|
||||
|
||||
// ✅ 计算当前像素的 UV 坐标
|
||||
float u = (float)atlasX / (float)textureSize;
|
||||
float v = (float)atlasY / (float)textureSize;
|
||||
|
||||
// ✅ 获取三角形的三个 UV 点
|
||||
const TexCoord& uv0 = scene.mesh.faceTexcoords[vf.faces[0] * 3 + 0];
|
||||
const TexCoord& uv1 = scene.mesh.faceTexcoords[vf.faces[0] * 3 + 1];
|
||||
const TexCoord& uv2 = scene.mesh.faceTexcoords[vf.faces[0] * 3 + 2];
|
||||
|
||||
// ✅ 计算点到三角形三条边的有符号距离(UV空间)
|
||||
// 使用重心坐标或点到线段的距离公式
|
||||
auto pointToLineDistance = [](float px, float py,
|
||||
float x1, float y1,
|
||||
float x2, float y2) -> float {
|
||||
float dx = x2 - x1;
|
||||
float dy = y2 - y1;
|
||||
if (dx == 0.0f && dy == 0.0f) return std::sqrt((px-x1)*(px-x1) + (py-y1)*(py-y1));
|
||||
|
||||
float t = ((px - x1) * dx + (py - y1) * dy) / (dx*dx + dy*dy);
|
||||
t = std::max(0.0f, std::min(1.0f, t));
|
||||
|
||||
float closestX = x1 + t * dx;
|
||||
float closestY = y1 + t * dy;
|
||||
return std::sqrt((px - closestX)*(px - closestX) +
|
||||
(py - closestY)*(py - closestY));
|
||||
};
|
||||
|
||||
// 计算到三条边的距离
|
||||
float d0 = pointToLineDistance(u, v, uv0.x, uv0.y, uv1.x, uv1.y);
|
||||
float d1 = pointToLineDistance(u, v, uv1.x, uv1.y, uv2.x, uv2.y);
|
||||
float d2 = pointToLineDistance(u, v, uv2.x, uv2.y, uv0.x, uv0.y);
|
||||
|
||||
// 取最小距离作为到三角形边界的距离
|
||||
float distToEdge = std::min({d0, d1, d2});
|
||||
|
||||
// 转换为像素距离
|
||||
float pixelDist = distToEdge * textureSize;
|
||||
|
||||
// ✅ Gutter 衰减逻辑(只衰减评分,不修改颜色!)
|
||||
float gutterWeight = 1.0f;
|
||||
if (pixelDist < gutter) {
|
||||
// 使用平滑衰减函数(二次曲线)
|
||||
gutterWeight = (pixelDist * pixelDist) / (gutter * gutter);
|
||||
|
||||
// 极边缘处给极低权重,但不跳过
|
||||
if (pixelDist < 0.5f) {
|
||||
gutterWeight = 0.01f; // 极低权重,几乎不会被选中
|
||||
}
|
||||
}
|
||||
|
||||
size_t idx = atlasY * textureSize + atlasX;
|
||||
TexelScore& ts = m_texelScores[idx];
|
||||
|
||||
@@ -14352,11 +14404,13 @@ bool MeshTexture::RasterizeVirtualFaces(
|
||||
? -1.0f
|
||||
: virtualFaceViewWeights[i][0];
|
||||
|
||||
// ✅ 只接受更高评分的写入
|
||||
if (currentScore > ts.score) {
|
||||
// ✅ 只衰减评分,不修改颜色!
|
||||
float finalScore = currentScore * gutterWeight;
|
||||
|
||||
if (finalScore > ts.score) {
|
||||
atlas(atlasY, atlasX) =
|
||||
Pixel8U{color[2], color[1], color[0]};
|
||||
ts.score = currentScore;
|
||||
ts.score = finalScore;
|
||||
ts.viewID = viewID;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user