首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自动生成UV坐标算法

自动生成UV坐标算法
EN

Stack Overflow用户
提问于 2013-09-03 02:25:34
回答 3查看 16.3K关注 0票数 17

我正在为自己的一个工具编写自己的uv编辑器,并尝试尽可能多地整合投影算法。我需要一个任意的网格,并为每个顶点设置uv坐标。

到目前为止,我有平面和最小二乘共形贴图。

我想合并更多,例如三平面,柱面,球面,但我有一个非常困难的时间来定位信息来执行算法。三平面似乎可以生成一种颜色,但我需要获取UV坐标中的所有内容。

如果您能帮忙,我们将非常感激!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-09-04 10:44:16

三平面

忘了它吧:它不是投影算法(一种提供UV坐标的算法),并且您无法从中获得UV坐标。它是一种渲染算法,它为您提供通过混合使用每个X-Y-Z平面投影获得的颜色而获得的颜色。

圆柱形,球形

与平面类似,这些都是非常简单的投影算法,可以直接从XYZ值提供UV值,而无需考虑与其他顶点的连接性。

对于圆柱形,

  • :将(x,y,z)转换为Cylindrical Coordinates (

,z),并用作UV坐标u=θ和v=z

  • 对于球形:在Spherical Coordinates (r,θ,φ)中转换(x,y,z),并用作UV坐标u=θ和v=φ

当然,您可以切换X、Y和Z的角色以使用不同的轴进行投影,或者执行一些平移/旋转/缩放以获得更多控制(与控制用于平面投影的平面的大小和方向的方式相同)。

立方

首先,需要确定将网格的每个面指定给哪个“投影面”。我将投影面命名为X、-X、Y、-Y、Z和-Z,如下图所示(我假设X、Y和Z轴的颜色分别为红色、绿色和蓝色):

为此,您只需找到法线的哪个坐标(nx,ny,nz)具有最大的绝对值,并将其分配给与该轴和符号对应的面。例如:

  • 如果n= (0.8,0.5,0.3),则对应面为X (| nx |为最大且nx为正)
  • 如果n= (0.3,0.8,0.5),则对应面为Y (| ny |为最大且ny为正)
  • 如果n= (0.3,-0.8,0.5),则对应面为-Y (|ny|为最大且ny为负)

然后,一旦知道将网格的每个面指定给哪个投影面,就可以将相应的平面投影应用于该面周围的顶点,以获得临时值(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,则应执行以下操作:

代码语言:javascript
复制
u = 2./3. + u_temp/3.;
v = 2./4. + v_temp/4.; 

最后,不要忘记复制属于具有不同平面投影(图片上不同颜色之间的边界)的两个面的UV顶点。实际上,网格的一些顶点可以(在大多数情况下也应该)在UV贴图中分割为几个位置,以获得良好的结果。

票数 30
EN

Stack Overflow用户

发布于 2013-11-13 01:38:37

立方映射

执行此操作的标准方法是基于(rx,ry,rz)向量,首先在表中查找一些值。这些值用于每个顶点的(s,t) (或(u,v))纹理坐标。

首先找到反射矢量R= 2(N点V)N - V,其中V=顶点,N=法线,R反射矢量(rx,ry,rz)

代码语言:javascript
复制
                      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)坐标。

代码语言:javascript
复制
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

请分享你的最小二乘共形映射算法来生成UV坐标。谢谢。

票数 3
EN

Stack Overflow用户

发布于 2013-09-03 05:05:29

您应该从siggraph课程Mesh Parameterization: Theory and Practice开始,然后查看引用的论文,了解您正在实现的算法的详细信息

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18578943

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档