 Allegro.cc Forums » Programming Questions » spherical texture coordinates

 This thread is locked; no one can reply to it.  spherical texture coordinates
Mike Farrell
Member #248
April 2000 I'm trying to wrap a texture around a sphere (similarly to the way GLU quadric spheres are textured) using its geometry as input.

I've written a function to convert the sphere's xyz rectangular coordinates to spherical ones and then in turn am using the u & v (phi & theta) spherical parameters as my texture coordinates. The only problem here is that u (the latitudal coordinate) repeats after it reaches 360 degrees. This is causing the texture coordinate to wrap around incorrectly at the pole (see attached screenshot).

For some reason, I just can't figure out how to fix this problem.

Here's my code

 1 2 //real's are just floats 3 //texc behaves like a 2d array where 4 //index 0 is the r (horizontal) texture coordinate 5 //and index 1 is the t (vertical) texture coordinate 6 //v is the incoming 3D rectangular coordinate of a point 7 //on the sphere and r is a supplied radius to save computation 8 9 static inline void spherical_texc(real r, const Vertex3D &v, Vertex &texc) 10 { 11 real phi, theta, 12 s = sqrt(v*v + v*v); 13 14 phi = acos(v/r); 15 if(s != 0) 16 theta = M_PI/2+((0 <= v) ? asin(v/s) : (M_PI-asin(v/s))); 17 else theta = 0; 18 19 texc = theta/(2*M_PI); 20 texc = phi/M_PI; 21 }

 Plucky Member #1,346 May 2001 Quote: The only problem here is that u (the latitudal coordinate) repeats after it reaches 360 degrees. ?? phi can only be from 0 to 180 deg due to "acos". Are you talking about theta? Perhaps you need to describe the problem better; the picture wasn't that helpful.Perhaps things can be simplified by: ```const float precision = 0.000001; if (v > precision || v < -precision) theta = atan2(v / v); else theta = 0.; ``` or similar.
Mike Farrell
Member #248
April 2000 The problem lies in the conversion from rectangular coordinates to spherical ones.

Since theta wraps around the sphere like latitude lines wrap around the earth, once you pass 360 degrees, you reset to 0. This makes the vertex that converts to a theta of 0 in spherical coordinates, also able to have the value 360. That may not matter for degrees, but when texture mapping, 0 and 1 and definitely two different values.

My desired result is what happens in blender when you turn the mapping mode to spherical instead of flat. I even downloaded the blender source code and used their spherical coordinate function thinking that would fix it. But I still had the EXACT same problem. Which means blender must fix the issue elsewhere but I can't find it in their code.

In other words, acos is necessary because of the nature of the problem.

Here's blenders code, it pretty much does the same thing my above algorithm does (and doesn't fix my problem still)

 1 /*from blender source code *********/ 2 static float saacos(float fac) 3 { 4 if(fac<= -1.0f) return (float)M_PI; 5 else if(fac>=1.0f) return 0.0; 6 else return (float)acos(fac); 7 } 8 9 static void spheremap(float x, float y, float z, float &u, float &v) 10 { 11 float len; 12 13 len = sqrt(x*x+y*y+z*z); 14 if(len>0.0) 15 { 16 if(x==0.0 && y==0.0) u = 0.0; /* othwise domain error */ 17 else u = (1.0 - atan2(x,y)/M_PI )/2.0; 18 19 z/=len; 20 v = 1.0- saacos(z)/M_PI; 21 } 22 } 23 /******************************/

 Plucky Member #1,346 May 2001 Have you checked to see if 'u' is ever > 1.0?Perhaps the problem is in your vertices? Overlapping points? And that the blender code has no need to fix "the problem" to begin with.
 Mike Farrell Member #248 April 2000 I've checked the sphere vertex code many times over, the vertices are fine. If I do a flat method of texture mapping, it comes out ok.
 Plucky Member #1,346 May 2001 I understand the problem now. You want the u coordinates for the problem area to be say 0.95 --> 1.0, instead you're getting 0.95 --> 0.0 . Well, one way is to add another meridian of vertices that overlap the "starting points" where u=0, and set those texture coordinates to be u=1, instead.
 Mike Farrell Member #248 April 2000 I'm gonna try something else I think. Since the vertices are stored at the polygon level and not the vertex level, I'm going to essentially store the two sets of polygons that own the pole vertices: the ones with an angle increasing (start of the pole), and the ones with the angle decreasing (at the end of the pole) and that will be may way to determine whether I should use 0.0 or 1.0.I'll post back if I have more trouble
 Go to: Allegro Development Installation, Setup & Configuration Allegro.cc Comments Off-Topic Ordeals The Depot Game Design & Concepts Programming Questions Recent Threads