Question

I am having buggy texture map on my sphere. The issue is well known but solution is rare.

This is my code for generating UVs for a sphere.

T = triangles, Nv = vertex normals.

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;
}

Output: http://i.stack.imgur.com/luhgZ.jpg ![enter image description here][1]

As you can see in the figure, my code is generating long strip at one side of the sphere. The solution is here .. http://sol.gfxile.net/sphere/index.html but couldn't figure it out.. How can I solve this issue ? any suggestion?

# Update 1:#

This code also doesn't work for me.. I don't know what wrong in it. still the same ugly seam I am getting. ???

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;
}
Was it helpful?

Solution

The issue is because you're wrapping texcoords around the sphere.

If I take a horizontal slice of your globe and stretch it out flat, the x texcoords look something like this;

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

The ugly seam comes from the area's I've marked with the carats (^). In between all your other vertices, the texture coordinates are nicely interpolated from n to n+0.1. However on the last pair of vertices, it's being interpolated all the way between 0.9 and 0, meaning that it flips and squishes the entire texture into that single seam (which is the ugly tear you are seeing.

To solve it, what you need to do is to create a duplicate pair of vertices around the seam, with texture coordinate 1.0. These should like directly on top of the original vertices, and they should probably not connect to them. The texcoord should look like this:

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

With the 1.0 and the 0 lying on top of each other. Then all areas between vertices will be interpolated evenly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top