Sphere UV mapping. Texture Streched

I am trying to write a sphere mesh algorithm. Unfortunately, is the texture stretched vertically at the very end of the image. This should be near U 0.99~.

Below is the code used for the sphere creation. In the Image below that you can see a sphere created by Maya with the correct textures applied to it. Therefore, the issue is defiantly the UV map created by this code.

If I increase the number of parallels that are wrongly called meridians. Then the texture looks nearly spot on, but one thin line of garbage.

Hope someone sees the issue. I worked on it for 2 days now :(
There is a live version online for a closed examination of the object. https://upmkuhn.github.io/AGAV/AGAV/

Btw what is the correct terminology for such an issue?

function makeSphere(radius, numParallels, numMeridians)
{
var index = 0;
var grid = [];
var vertecies = [];
var normals = [];
var texture = [];
var faces = [];

for (var p = -1; p < numParallels; p++)
{
var row = [];
var parallel = Math.PI * (p +1) / numParallels
for (var m = -1; m < numMeridians; m++) {
var meridian = 2.0 * Math.PI * m / numMeridians
var cartesian = sphericalToCartesian(radius, meridian, parallel);
var vec3xyz = vec3.create(cartesian);
vertecies.push(cartesian);

//NORMALS
vec3.normalize(vec3xyz, vec3xyz);
normals.push(vec3xyz);

x = vec3xyz[0] == 0 ? 0 : vec3xyz[0];
y = vec3xyz[1] == 0 ? 0 : vec3xyz[1];
z = vec3xyz[2] == 0 ? 0 : vec3xyz[2];
//UV
var u = (Math.atan2(x, z) / (2 * Math.PI) + 0.5);
var v = y * 0.5 + 0.5;

texture.push(u,v);
row.push(index++);
}
grid.push(row);
}

for (var i = 0; i < texture.length;i+=2)
{
var u = texture[i];
var v = texture[i+1];
if (Math.abs(u-v) < 0.5)
{
}
}

for (var p = 0; p < (numParallels ); p++) {
for (var m = 0; m < numMeridians; m++) {

if (m < numMeridians) {
var p1 = grid[p][m];
var p2 = grid[p + 1][m];
var p3 = grid[p][m + 1];
faces.push(p1, p3, p2, grid[p + 1][m + 1]);
}
}
}

return {
vertecies: vertecies,
normals: normals,
texture: texture,
faces: faces
}
}

function sphericalToCartesian(radius, azimuth, elevation)
{
var x = radius * Math.sin(elevation) * Math.cos(azimuth)
var y = radius * Math.sin(elevation) * Math.sin(azimuth)
var z = radius * Math.cos(elevation)
return [x , y , z];
}

• Try making the u component p / numParallels and the v component m / numMeridian – Bálint Jan 25 '17 at 6:44
• I am not quit sure what you mean. u = (p / numParallels); v = (m / numMeridians); This unfortunately doesn't work :( Correct me if I did it wrong. Going to play around with those values now and see how else I can make them fit. Thanks – Martin Kuhn Jan 25 '17 at 7:05
• Sorry my bad it did work. I have mistaken a white color as an unmapped area. The problem is I need to shift it so that the polar orbits are at the top. right now there are at the left side. – Martin Kuhn Jan 25 '17 at 7:22
• The pols are on side and Alaska is squeezed to tightly together. :( – Martin Kuhn Jan 25 '17 at 7:35
• I know why that happens, let me post an answer – Bálint Jan 25 '17 at 7:43

1 Answer

You should set u to m / numMeridian and v to p / numParalell

• Stackoverflow doesn't allow me to post 2 links. So I post the image here as a link. pl.vc/1kirlb The left hand side shows u=p v =m and the right hand side shows u=m v =p. I think your former comment was correct. Sorry man didn't sleep all night. Any idea how to shift them so the pols are correct? Thanks :) – Martin Kuhn Jan 25 '17 at 7:57
• @Martin try subtracting or adding 0.5 to one of the coordinates – Bálint Jan 25 '17 at 8:16
• I found a similar streching issue on it. It is in the ocean. I also found an explanation about what is happening. The problem is that some triangles will map to both ends of the map. After all, the right edge of the map meets the left edge. Imagine a triangle hanging off one edge. The problem is that the trig functions simply wrap the value around. So, you end of with a triangle the has two vertices on one edge of the map and one on the other edge. This causes all of the map between these points to be smashed into the image mapped onto the polygon http:/cse.msu.edu/~cse872/tutorial4.html – Martin Kuhn Jan 25 '17 at 8:54
• I don;t quit understand how to apply that solution to my implementation. // The second vertex tx = atan2(b[0], b[2]) / (2. * GR_PI) + 0.5; ty = asin(b[1]) / GR_PI + .5; if(tx < 0.75 && tx1 > 0.75) tx += 1.0; else if(tx > 0.75 && tx1 < 0.75) tx -= 1.0; glTexCoord2f(tx, ty); – Martin Kuhn Jan 25 '17 at 8:55
• @Martin Do you by any chance use a 2d map projection for this? Keep in mind, that using projections like the mercator projection will result in distortions – Bálint Jan 25 '17 at 9:37