Sign up ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Could someone please explain how it would be possible to create a sphere vertices, indices and texture coordinates? There is a surprising lack of documentation on how to do so and it is something that I am interested in learning.

I have tried the obvious, googling, looking on, etc. However, nothing covers the generations of spherical points, indexing them, and texturing.

share|improve this question
I am not going to downvote or vote to close this, but are you really telling me that not a single result from was useful? If that's the case you'll need to explain what your problem is in more detail. –  user744 Aug 30 '11 at 4:25
Ta da :… –  dcousens Aug 30 '11 at 4:52
Search for icosphere. Much smarter than dumb "polar sphere" which produces useless faces. –  Notabene Aug 30 '11 at 7:07
Worth noting, for some simple purposes a perfectly fine "sphere" is a quad with a circular texture facing the camera. –  aaaaaaaaaaaa Aug 30 '11 at 20:10
Here is how I implemented it for the skydome in my game. –  danijar Aug 1 '13 at 22:14

3 Answers 3

There are 2 ways to do it:

  1. Walk theta and phi in spherical coordinates, generate faces and tris

  2. Create an icosahedron and recursively subdivide faces until desired tessellation reached.

Sphere using spherical coordinates walk

For the first way, you just use a double nested for to walk theta and phi. As you walk theta and phi, you spin triangles to create your sphere.

enter image description here

The code that does it will look something like this:

for( int t = 0 ; t < stacks ; t++ ) // stacks are ELEVATION so they count theta
  real theta1 = ( (real)(t)/stacks )*PI ;
  real theta2 = ( (real)(t+1)/stacks )*PI ;

  for( int p = 0 ; p < slices ; p++ ) // slices are ORANGE SLICES so the count azimuth
    real phi1 = ( (real)(p)/slices )*2*PI ; // azimuth goes around 0 .. 2*PI
    real phi2 = ( (real)(p+1)/slices )*2*PI ;

    //phi2   phi1
    // |      |
    // 2------1 -- theta1
    // |\ _   |
    // |    \ |
    // 3------4 -- theta2

    //vertex1 = vertex on a sphere of radius r at spherical coords theta1, phi1
    //vertex2 = vertex on a sphere of radius r at spherical coords theta1, phi2
    //vertex3 = vertex on a sphere of radius r at spherical coords theta2, phi2
    //vertex4 = vertex on a sphere of radius r at spherical coords theta2, phi1

    // facing out
    if( t == 0 ) // top cap
      mesh->addTri( vertex1, vertex3, vertex4 ) ; //t1p1, t2p2, t2p1
    else if( t + 1 == stacks ) //end cap
      mesh->addTri( vertex3, vertex1, vertex2 ) ; //t2p2, t1p1, t1p2
      // body, facing OUT:
      mesh->addTri( vertex1, vertex2, vertex4 ) ;
      mesh->addTri( vertex2, vertex3, vertex4 ) ;

So note above, its important to wind the top cap and bottom cap using only tris, not quads.

Icosahedral sphere

TO use an icosahedron, you just generate the points of the icosahedron and then wind up triangles from it. The vertices of an icosahedron sitting at the origin are:

(0, ±1, ±φ)
(±1, ±φ, 0)
(±φ, 0, ±1)
where φ = (1 + √5) / 2 

You then have to just look at a diagram of an icosahedron and wind faces from those verts. I already have code that does it here.

share|improve this answer

If the points don't have to be locally uniform, but should be globally uniform, and don't have to follow any set pattern, you can use a variant of dart-throwing algorithm to distribute n points on a sphere with radius r, on average dist points apart. These values are then roughly:

  1. If you want to have a specific amount of vertices:
    • n = (desired amount of vertices)
    • dist = 2 × r × √(π / n)
  2. If you want to have a specific average distance between the vertices:
    • n = 4 × π × (r / dist)2
    • dist = (desired average distance)

In the simplest case, you can then uniformly pick points at random by picking two uniformly distributed variables u and v from (0, 1) and calculating the polar coordinates from them according to the formulas θ = 2 × π × u and ϕ = arc cos (2 × v - 1); then dismissing any points which lie too near to the already picked points. For a slightly more complex and significantly better-performing algorithm, see "Dart Throwing on Surfaces" by Cline, Jeschke, White, Razdan and Wonka.

After you picked your first four points (assuming no three of them are degenerate, that is - they don't lie on the same great circle, but that's highly unlikely), you can create four faces between them, and each time you add a new point, you can split the face it belongs to accordingly into three sub-faces.

For texturing purposes you can then map the points to a cube map.

share|improve this answer

There are two general approaches:

enter image description here

The leftmost is termed the uv-sphere and the rightmost an icosphere.

GLUT tends to use the uv approach: look at the function glutSolidSphere() in the freeglut sourcecode.

Here is an excellent article on producing an icosphere:

The uv-sphere looks like a globe. For many purposes it is perfectly fine, but for some use cases, e.g. if you want to deform the sphere, it is disadvantageous that the density of vertices is greater around the poles. Here the icosphere is better, its vertices are distributed evenly.

You may also find this interesting: it describes an approach to organising the faces into zones. gives an excellent description of how you might choose to texture them.

share|improve this answer
While the general idea is good, subdividing a Schläfli {3,5} polytope isn't the only way to do it. Generally, I prefer to work with the Schläfli {4,*} family ({4,3} in case of a sphere) for UV-mapping purposes. –  Martin Sojka Aug 30 '11 at 8:47
Finely tessellated icosahedral spheres are a bit more expensive to generate because of the need to recursively subdivide the faces. –  bobobobo Aug 1 '13 at 14:49

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.