2012-07-19 64 views
2

我在我的球体上有越野车纹理贴图。这个问题众所周知,但解决方案很少。OpenGL中球体的Bug坐标?

这是我为球体生成UV的代码。

T = trinagles,Nv =顶点法线。

for (int i=0; i<nbF; i++) 
{ 
    float tx1 = atan2(Nv[T[i].v1].x, Nv[T[i].v1].z)/(2.0f*M_PI) + 0.5f; 
    float ty1 = asinf(Nv[T[i].v1].y)/M_PI + 0.5f; 

    float tx2 = atan2(Nv[T[i].v2].x, Nv[T[i].v2].z)/(2.0f*M_PI) + 0.5f; 
    float ty2 = asinf(Nv[T[i].v2].y)/M_PI + 0.5f; 

    float tx3 = atan2(Nv[T[i].v3].x, Nv[T[i].v3].z)/(2.0f*M_PI) + 0.5f; 
    float ty3 = asinf(Nv[T[i].v3].y)/M_PI + 0.5f; 

    float n = 0.75f; 

    if(tx2 < n && tx1 > n) 
     tx2 += 1.0; 
    else if(tx2 > n && tx1 < n) 
     tx2 -= 1.0; 

    if(tx3 < n && tx2 > n) 
     tx3 += 1.0; 
    else if(tx3 > n && tx2 < n) 
     tx3 -= 1.0; 

    out_UV[T[i].v1].u = tx1; 
    out_UV[T[i].v1].v = ty1; 

    out_UV[T[i].v2].u = tx2; 
    out_UV[T[i].v2].v = ty2; 

    out_UV[T[i].v3].u = tx3; 
    out_UV[T[i].v3].v = ty3; 
} 

输出: http://i.stack.imgur.com/luhgZ.jpg [在这里输入的形象描述] [1]

正如你在图中看到的,我的代码是在球体的一侧产生长条形。解决方案是在这里.. http://sol.gfxile.net/sphere/index.html但无法弄清楚..我该如何解决这个问题?任何建议?

# Update 1:# 

此代码也不适用于我..我不知道它是什么错误。仍然是我得到的同样难看的缝。 ???

for (int i=0; i<nbV; i++) 
{ 
    out_UV[i].u = (float) atan2(Nv[i].x, Nv[i].z)/(2.0f*M_PI) + 0.5f; 
    out_UV[i].v = (float) (asin(Nv[i].y)/M_PI) + 0.5f; 
} 

float nx = 0.9f; 
float nv = 0.8f; 
for (int i=0; i<nbV-2; i++) 
{ 
    if (out_UV[i].u - out_UV[i+1].u > nx) 
     out_UV[i+1].u += 1.0f; 
    if (out_UV[i+1].u - out_UV[i].u > nx) 
     out_UV[i].u += 1.0f; 

    if (out_UV[i].u - out_UV[i+2].u > nx) 
     out_UV[i+2].u += 1.0f; 
    if (out_UV[i+2].u - out_UV[i].u > nx) 
     out_UV[i].u += 1.0f; 

    if (out_UV[i+1].u - out_UV[i+2].u > nx) 
     out_UV[i+2].u += 1.0f; 
    if (out_UV[i+2].u - out_UV[i+1].u > nx) 
     out_UV[i+1].u += 1.0f; 

    if (out_UV[i].v - out_UV[i+1].v > nv) 
     out_UV[i+1].v += 1.0f; 
    if (out_UV[i+1].v - out_UV[i].v > nv) 
     out_UV[i].v += 1.0f; 

    if (out_UV[i].v - out_UV[i+2].v > nv) 
     out_UV[i+2].v += 1.0f; 
    if (out_UV[i+2].v - out_UV[i].v > nv) 
     out_UV[i].v += 1.0f; 

    if (out_UV[i+1].v - out_UV[i+2].v > nv) 
     out_UV[i+2].v += 1.0f; 
    if (out_UV[i+2].v - out_UV[i+1].v > nv) 
     out_UV[i+1].v += 1.0f; 
} 

回答

6

这个问题是因为你在球体周围包裹着texcoords。

如果我把地球的一个水平切片伸展平坦,x texcoords看起来像这样;

0.7 0.8 0.9  0  0.1 0.2 0.3 0.4 
|------|------|------|------|------|------|------| 
       ^^^^^^ 
         |-wrapping around here 

丑陋的接缝来自该地区的我已经打上克拉(^)。在所有其他顶点之间,纹理坐标很好地从n内插到n+0.1。然而在最后的顶点对,它被插一路0.90之间,这意味着它翻转和squishes整个纹理成单缝(这是你所看到的丑陋的眼泪。

为了解决这个问题,你需要做的是在接缝周围创建一对重复的顶点,纹理坐标为1.0,它们应该直接位于原始顶点的顶部,并且它们可能不应该与它们连接。texcoord应该如下所示:

     1.0 
0.7 0.8 0.9  |0  0.1 0.2 0.3 0.4 
|------|------|------||------|------|------|------| 

随着1.0和0位于彼此之上,那么顶点之间的所有区域将被均匀地插值

+0

感谢您的回复。 我不理解的是......什么是重复的顶点对?如何创建它们?你是说我需要更新网格顶点数据?例如球体有100个顶点,为了应用纹理贴图,我需要更新它,假设有120或140个顶点。像那样 ? 它不应该是这样吗?网格数据应该是相同的..无论如何..你可以请我建议我如何创建重复的顶点...? – furqan 2012-07-19 06:44:36

+0

我已更新新代码。仍然有相同的难看的缝。 – furqan 2012-07-19 07:25:47

+0

一个古典的问题,但它是我见过的最好的描述方式。谢谢! – 2013-04-09 16:55:14