Skip to main content

For anyone who is stuck with doing a proper spherical projection on a sphere and are always getting distortion at poles and edges , the below is the best and the ideal way to do it in C++. Hope it helps ! Let me know if you have any questions.

// SPHERICAL PROJECTION OF TEXTURE ON TO A SPHERE

// Use this method to texture map a sphere inside openGL,
// Directx 11 or even during ray tracking and path tracking 

// You will not get any artifacts at poles/edges by using this method 

int Slices = 32;
int Stacks = 32;
double Radius = 5.0;
float PI = 3.14159;
Vector3f Center = Vector3f(0,0,0);
float u =0 ,v =0;
int i = 0;
int j = 0;
// not using dynamic memeory and just hard coding the array 
// to not get any memory access violation errros
float uu[1524],vv[1524];

for (int stack = Stacks; stack >= 0; stack--)
	{
		for (int slice = Slices; slice >= 0; slice--)
		{
		uu[i] =	(double)slice / Slices ;
		vv[i] =	(double)stack / Stacks ;
		i++ ;
		}
	}

// Store all the vertices of the sphere and then 
// add the associated uv co-ordinates for each vertex. 
for (int stack = 0; stack <= Stacks; stack++)
    {
    	// for every stack on the sphere calculate phi 
        double phi = PI / 2 - stack * PI / Stacks;

        for (int slice = 0; slice <= Slices; slice++)
        {
        	// for every slice on the sphere calculate theta
            double theta = slice * 2 * PI / Slices;
            double x = -Radius * cos(phi) * sin(theta) + Radius;
            double y =  Radius * sin(phi) ;
            double z = -Radius * cos(phi) * cos(theta) ;

            Vector3f dir = Vector3f(x , y, z);
			u = uu[j];
			v = vv[j];
			// Now that x,y,z co-ordinates, store the vertex in your array of vertices
			m->AddVertex(Vertex(dir + Center, Color(255,255,255), u, v, dir));
			// The above is a pseudo code to pass the actual vertex, color of vertex, uv co-ordinates and the normal 
            j++;
        }
    }
// Add the traingles in a set of 3 vertices 
for (int stack = 0; stack < Stacks; stack++)
{
	// from the combination of stacks and slices we can create triangle indices
    int index1 = (stack + 0) * (Slices + 1);
    int index2 = (stack + 1) * (Slices + 1);

    for (int slice = 0; slice < Slices; slice++)
    {
    	// the if statements take care of the edge cases which would otherwise give the distortion at poles
        if (stack != 0)
        {
			m->AddTriangle((index1 + slice),index2 + slice,index1 + slice + 1);
        }

        if (stack != Stacks - 1)
        {
			m->AddTriangle((index1 + slice + 1),(index2 + slice),(index2 + slice + 1));
        }
    }
}

 

Leave a Reply