0

I've generated a geodesic sphere for opengl rendering following a question on here and I'm trying to put texture on it. I came up with the following code by reversing an algorithm for a point on a sphere:

//complete circle equation is as follows
///<Summary>
///x = r * sin(s) * sin(t)
///y = r* cos(t)
///z = r * cos(s) * sin(t)
///</Summary>


float radius = 1.0f;

//T (height/latitude) angle
float angleT =  acos(point.y / radius) ;

//S (longitude )angle
float angleS = ( asin(point.x / (radius * sin(angleT)))) + (1.0f* M_PI);
float angleS2 =( acos(point.z / (radius * sin(angleT)))) + (1.0f * M_PI);

//Angle can be 0-PI (0-180 degs), divide by this to get 0-1
angleT = angleT / (M_PI);

//Angle can be 0-2PI (0-360 degs)S
angleS = angleS / ( M_PI *2 );
angleS2 = angleS2 / ( M_PI *2 );

//Flip the y co-ord
float yTex = 1 - angleT;
float xTex = 0.0f;

//I have found that angleS2 is valid 0.5-1.0, and angleS is valid (0.3-0.5)
if (angleS < 0.5f)
{
    xTex = angleS;
}
else
{
    xTex = angleS2;
}

return glm::vec2( xTex , yTex);

As you can see, I've found that both versions of calculating the S angle have limited valid ranges.

float angleS = ( asin(point.x / (radius * sin(angleT)))) + (1.0f* M_PI);
float angleS2 =( acos(point.z / (radius * sin(angleT)))) + (1.0f * M_PI);

S1 is gives valid answers between x texture co-ords 0.3 and 0.5 and S2 gives valid answers for between x texture co-ords 0.5 and 1.0 (Conversion to co-ords omitted above but present in first code example). Why is it that neither formula is giving me valid answers for under 0.3?

Thanks

Will

Correct on this side Correct on this side The weird border between working and not, probably caused by opengl's interpolation The weird border between working and not, probably caused by opengl's interpolation Reversed section Reversed section The image being used The image being used Edit: Here is the seam Seam

Figwig
  • 592
  • 1
  • 3
  • 16

1 Answers1

1

The equations you use to calculate the longitude angles are not correct seeing what you are trying to accomplish. For the longitude angle, the range you require is 0-360 degrees, which can not be obtained through asin or acos functions, because those functions only return results between -90 and 90 degrees or 0 to 180 degrees. You can, however, use the atan2 function, which returns values from the correct interval. The code I've been working with for the past 2 years is the following:

float longitude = atan2f(point.x, point.z) + (float)M_PI;

This equation will map the horizontal center of the texture in the direction of positive Z axis. If you want the horizontal center of the texture to be in the direction of positive X axis, add M_PI / 2.0.

NiceTry
  • 26
  • 3
  • Perfect! Don't know how I didn't see that.. Thanks! I do have a particularly horrible seam in the middle of the pacific but I'll work on solving that now. Thanks! – Figwig Aug 30 '19 at 13:31
  • @WillHain You're welcome. Can you provide any screenshots of the seam? – NiceTry Aug 30 '19 at 13:34
  • Added to the question – Figwig Aug 30 '19 at 15:15
  • Don't worry, fixed! – Figwig Aug 30 '19 at 15:41
  • To fix the seam, you need to duplicate the vertices at 180° longitude and assign texture coordinates at the lower end to one set and texture coordinates at the upper and to the other set. If you don't have vertices there, you need to create them. Otherwise, it will squish the entire texture into the gap in between. – Nico Schertler Aug 30 '19 at 19:12
  • I found that I could just use opengl's texture repeating function. If a triangle has the texture coord x value of 0.9 on one point, but 0.1 on an other, just add 1 to the small one and because the texture repeats it appears correctly – Figwig Aug 30 '19 at 19:14
  • @WillHain: But where would you add 1? You need the small values for the left side of the texture and the large values for the right side. – Nico Schertler Aug 30 '19 at 21:18
  • On the very far right of the texture, a triangle might overlap back into what would be round the seam. Say the x texture co-ord of the left most point on that triangle is 0.95 (355degs longitude say), and then the right most point's x texture coord is 0.05 ( 005 degs longitude for example), obviously this triangle would be reversed and look awful. However, if you simply add one, the texture co-ord for the one over the seam is 1.05, and because opengl allows GL_TEXTURE_REPEAT this looks correct :) Edit: corrections – Figwig Aug 31 '19 at 22:09