使用插值法在重心坐标处获得正确的UV

4
我正在尝试实现凸多边形的正确纹理映射。我有一个由n个三角形组成的多边形,对于每个三角形,我都计算了重心坐标,它们是每个三角形中的uv坐标,但仅在每个三角形内部的[0..1]范围内,而不是整个多边形。如何插值每个uv坐标以使其覆盖整个纹理(而不是像现在这样重复)?
现在看起来像这样: enter image description here
//region.triangulatedVectors = List<Vector2> // triangle points in CCW

//foreach triangle 
for (int i = 0;i<region.triangulatedVectors.size();i+=3){
    float aX = region.triangulatedVectors.get(i).x;
    float aY = region.triangulatedVectors.get(i).y;
    float bX = region.triangulatedVectors.get(i+1).x;
    float bY = region.triangulatedVectors.get(i+1).y;
    float cX = region.triangulatedVectors.get(i+2).x;
    float cY = region.triangulatedVectors.get(i+2).y;
    Vector2 bary0 = new Vector2();
    Vector2 bary1 = new Vector2();
    Vector2 bary2 = new Vector2();
    Vector2 a = new Vector2(aX, aY);
    Vector2 b = new Vector2(bX, bY);
    Vector2 c = new Vector2(cX, cY);
    GeometryUtils.barycentric(a, a, b, c, bary0);
    GeometryUtils.barycentric(b, a, b, c, bary1);
    GeometryUtils.barycentric(c, a, b, c, bary2);
    //first point 
    texCoords[k++] = bary0.x;
    texCoords[k++] = bary0.y;
    texCoords[k++] = bary1.x;
    texCoords[k++] = bary1.y;
    texCoords[k++] = bary2.x;
    texCoords[k++] = bary2.y;
    //TODO , interpolate
}

看起来处理2D有3种方法:Wachspress、离散谐波和均值。


你并没有清楚地表达你想让它看起来像什么。如果你想让多边形像正方形一样被纹理映射,你需要为每个顶点计算UV坐标...但也许你想用不同的纹理方式呢? - Jyro117
1个回答

0

使用广义重心坐标来映射这两个多边形(一个n边形和另一个正方形),您可以在正方形周围添加人工顶点,以便将一个$n$边形映射到另一个。例如,this image 显示了一个八边形和一个增加了边中点的正方形,也有八个顶点。

然后,在原始多边形上,您定义一些广义重心坐标:

x = L1(x) v1 + L2(x) v2 + ... + Ln(x) vn

L1、L2、...、Ln等特定函数由您选择的任何广义重心坐标定义,例如平均值Wachspress等。

对于具有额外匹配顶点的正方形,也定义了相应的广义重心坐标,即

y = M1(y) w1 + M2(y) w2 + ... + Mn(y) wn

现在,给定多边形中的点x,我们使用多边形的重心坐标但使用正方形中的顶点位置计算关联点y(即我们可以查找纹理的(u,v))。

y = L1(x)w1 + L2(x)w2 + ... + Ln(x)wn

一些注意事项:

  • 按照这种方法,您可能不想使用Wachspress坐标。当在直线边缘中间添加这些额外的顶点时,它们的表现不佳。这张图片(来自这里)展示了Wachpress坐标在这种情况下的表现。
  • 仍然需要决定在哪里分割正方形的边缘以获得匹配数量的顶点,以及如何将多边形和正方形之间的顶点关联起来。这些决策肯定会影响纹理的拉伸和扭曲程度。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接