如何 compute/deduce 来自相邻顶点 UV 的新顶点 UV
How to compute/deduce new vertex UVs from adjacent vertices UVs
我有一个 3D 模型,它已经有了我能想到的所有缓冲区:位置、法线、uvs 等。
我想修改它的几何形状(移动现有顶点或创建新顶点),例如,对我的边缘进行倒角。
我可以很容易地计算出新位置和新法线(3D 向量),但我想知道如何计算新 UV(2D 向量),或者更确切地说,从相邻顶点 UV 中推导 它们.
如果有人知道如何以通用方式做到这一点,那就太好了。但也许我的具体用例提供了更多有用的数据:
在我的特定用例中,新顶点 (D) 将位于角 α (BAC) 的平分线上,我知道这一点。此外,我知道每个顶点的 3D 位置,我有所有距离 AC、AB 和 AD。
看来我应该复习我的几何课。三角学足以解决这个问题吗?
提前致谢!
在这种特定情况下,您可以使用 ABC 三角形找到 D。计算平分线和 BC 的交点(我们称之为 E),找到它的 UV 和 AE 距离。然后根据这些距离在 A 和 E 之间进行插值。
如果 D 点在三角形之外,在某些情况下它可能仍然有效。
在更一般的方法中,我会在您的图像上方添加一些点(例如 F),但未显示。基本上,您需要找到包围新点的最小多边形,并用它来计算新的 UV。
终于找到 this solution 完美回答了问题!
使用重心插值可以很容易地从新的点位置检索新的 UV。
这是 javascript 中使用 BabylonJS 进行向量 类 和操作的通用代码:
var f1 = p1.subtract(f);
var f2 = p2.subtract(f);
var f3 = p3.subtract(f);
var va = BABYLON.Vector3.Cross(p1.subtract(p2), p1.subtract(p3));
var va1 = BABYLON.Vector3.Cross(f2, f3);
var va2 = BABYLON.Vector3.Cross(f3, f1);
var va3 = BABYLON.Vector3.Cross(f1, f2);
var a = va.length();
var a1 = va1.length() / a * Math.sign(BABYLON.Vector3.Dot(va, va1));
var a2 = va2.length() / a * Math.sign(BABYLON.Vector3.Dot(va, va2));
var a3 = va3.length() / a * Math.sign(BABYLON.Vector3.Dot(va, va3));
return uv1.scale(a1).addInPlace(uv2.scale(a2)).addInPlace(uv3.scale(a3));
与:
- p1,p2,p3三个Vector3的三角点位置
- f一个新点位置的Vector3
- uv1,uv2,uv3三个Vector2的三角点uvs
这适用于三角形 p1p2p3 平面上的任何点,包括三角形以外的点。
显然,如果三个点对齐,这就不行了,它们必须形成一个面积大于零的三角形。
我有一个 3D 模型,它已经有了我能想到的所有缓冲区:位置、法线、uvs 等。 我想修改它的几何形状(移动现有顶点或创建新顶点),例如,对我的边缘进行倒角。 我可以很容易地计算出新位置和新法线(3D 向量),但我想知道如何计算新 UV(2D 向量),或者更确切地说,从相邻顶点 UV 中推导 它们.
如果有人知道如何以通用方式做到这一点,那就太好了。但也许我的具体用例提供了更多有用的数据:
在我的特定用例中,新顶点 (D) 将位于角 α (BAC) 的平分线上,我知道这一点。此外,我知道每个顶点的 3D 位置,我有所有距离 AC、AB 和 AD。
看来我应该复习我的几何课。三角学足以解决这个问题吗?
提前致谢!
在这种特定情况下,您可以使用 ABC 三角形找到 D。计算平分线和 BC 的交点(我们称之为 E),找到它的 UV 和 AE 距离。然后根据这些距离在 A 和 E 之间进行插值。 如果 D 点在三角形之外,在某些情况下它可能仍然有效。
在更一般的方法中,我会在您的图像上方添加一些点(例如 F),但未显示。基本上,您需要找到包围新点的最小多边形,并用它来计算新的 UV。
终于找到 this solution 完美回答了问题!
使用重心插值可以很容易地从新的点位置检索新的 UV。 这是 javascript 中使用 BabylonJS 进行向量 类 和操作的通用代码:
var f1 = p1.subtract(f);
var f2 = p2.subtract(f);
var f3 = p3.subtract(f);
var va = BABYLON.Vector3.Cross(p1.subtract(p2), p1.subtract(p3));
var va1 = BABYLON.Vector3.Cross(f2, f3);
var va2 = BABYLON.Vector3.Cross(f3, f1);
var va3 = BABYLON.Vector3.Cross(f1, f2);
var a = va.length();
var a1 = va1.length() / a * Math.sign(BABYLON.Vector3.Dot(va, va1));
var a2 = va2.length() / a * Math.sign(BABYLON.Vector3.Dot(va, va2));
var a3 = va3.length() / a * Math.sign(BABYLON.Vector3.Dot(va, va3));
return uv1.scale(a1).addInPlace(uv2.scale(a2)).addInPlace(uv3.scale(a3));
与:
- p1,p2,p3三个Vector3的三角点位置
- f一个新点位置的Vector3
- uv1,uv2,uv3三个Vector2的三角点uvs
这适用于三角形 p1p2p3 平面上的任何点,包括三角形以外的点。
显然,如果三个点对齐,这就不行了,它们必须形成一个面积大于零的三角形。