我正在为自己的工具编写自己的uv编辑器,并且我正在尝试将尽可能多的算法合并到投影中。我需要采用任意网格,并为每个顶点制作uv坐标。
到目前为止,我有平面和最小二乘保形贴图。
我想加入更多,例如三平面,圆柱,球面,但我很难找到信息来执行算法。三平面似乎会产生一种颜色,但我需要在UV坐标中获取所有颜色。
非常感谢帮助!!
答案 0 :(得分:25)
<强>三平面强>
忘了它:它不是投影算法(一种为你提供UV坐标的算法),你无法从中获取UV坐标。这是一个渲染算法,它为您提供了一种颜色,通过混合使用每个X-Y-Z平面投影分别获得的颜色。
Cylindrincal,Spherical
与平面一样,这些是非常简单的投影算法,直接从XYZ值为您提供UV值,而不考虑与其他顶点的连接。
当然,您可以使用不同的轴切换X,Y和Z的角色,或者执行一些平移/旋转/缩放以获得更多控制(与控制大小和方向相同的方式)你用于平面投影的平面。)
<强>立方强>
首先,您需要确定为网格的每个面分配哪个“投影面”。我将投影面X,-X,Y,-Y,Z和-Z命名为如下图所示(其中我假设X,Y和Z轴分别具有红色,绿色和蓝色):
为此,您只需找到法线(nx,ny,nz)的哪个坐标具有最大绝对值,并将其指定给与此轴和符号对应的面。例如:
然后,一旦知道为网格的每个面分配哪个投影面,就可以将相应的平面投影应用于该面周围的顶点以获得临时值(u_temp,v_temp)∈[0,1] x [0,1]。
下一步是将该值uv_temp∈[0,1] x [0,1]变换为包含在较小正方形中的值uv,如上面的图像A所示。例如,如果你应用投影“X”,那么你想要uv∈[2 / 3,3 / 3] x [2 / 4,3 / 4],那么你会这样做:
u = 2./3. + u_temp/3.;
v = 2./4. + v_temp/4.;
最后,最后一步是不要忘记复制属于具有不同平面投影的两个面的UV顶点(图片上不同颜色之间的边界)。实际上,网格的某些顶点可以(并且在大多数情况下应该)在UV贴图中的几个位置分割,以获得不错的结果。
答案 1 :(得分:2)
立方映射
基于(rx,ry,rz)向量执行此操作的标准方法是首先在表中查找某些值。这些值用于每个顶点的(s,t)(或(u,v))纹理坐标。
首先找到反射矢量 R = 2(N点V)N - V,其中V =顶点,N =正常,R反射矢量(rx,ry,rz)
major axis
direction sc tc ma
--------- --- --- --
+rx -rz -ry rx
-rx +rz -ry rx
+ry +rx +rz ry
-ry +rx -rz ry
+rz +rx -ry rz
-rz -rx -ry rz
一旦为sc,tc和ma指定了值,可以使用以下公式计算该面的(s,t)坐标。
if((rx >= ry) && (rx >= rz))
{
sc = -rz;
tc = -ry;
ma = fabs(rx); //absolute value
s = ((sc/ma) + 1) / 2;
t = ((tc/ma) + 1) / 2;
cout << "+rx (" << s << "," << t << ")" << endl;
}
if((rx <= ry) && (rx <= rz))
{
sc = +rz;
tc = -ry;
ma = fabs(rx);
s = ((sc/ma) + 1) / 2;
t = ((tc/ma) + 1) / 2;
cout << "-rx (" << s << "," << t << ")" << endl;
}
if((ry >= rz) && (ry >= rx))
{
sc = +rx;
tc = +rz;
ma = fabs(ry);
s = ((sc/ma) + 1) / 2;
t = ((tc/ma) + 1) / 2;
cout << "+ry (" << s << "," << t << ")" << endl;
}
if((ry <= rz) && (ry <= rx))
{
sc = +rx;
tc = -rz;
ma = fabs(ry);
s = ((sc/ma) + 1) / 2;
t = ((tc/ma) + 1) / 2;
cout << "-ry (" << s << "," << t << ")" << endl;
}
if((rz >= ry) && (rz >= rx))
{
sc = +rx;
tc = -ry;
ma = fabs(rz);
s = ((sc/ma) + 1) / 2;
t = ((tc/ma) + 1) / 2;
cout << "+rz (" << s << "," << t << ")" << endl;
}
if((rz <= ry) && (rz <= rx))
{
sc = -rx;
tc = -ry;
ma = fabs(rz);
s = ((sc/ma) + 1) / 2;
t = ((tc/ma) + 1) / 2;
cout << "-rz (" << s << "," << t << ")" << endl;
}
参考 http://www.unc.edu/~zimmons/cs238/maps/cubeind.html
球面,立方体和抛物线环境映射http://www.unc.edu/~zimmons/cs238/maps/environment.html
OP请你分享你的最小二乘保形映射算法来生成UV坐标。谢谢。
答案 2 :(得分:1)
您应该从siggraph课程Mesh Parameterization: Theory and Practice开始,然后查看引用的论文,了解您正在实施的算法的详细信息