Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I want to display a 3D textured sphere, and then rotate it in one direction. The direction will never change, and the camera will never move. One way is to actually create a spherical mesh, map a texture to it, rotate the sphere, and render in 3D.

My question is, is there a way to display a 2D circle, that looks like a rotating sphere, with just a 2D shader.

In other words, can someone think of a trick, like mapping a texture to the circle in a particular way, to give the appearance of an in-place rotating sphere, that is always viewed from the side?

I don't need exact shader code, I'm just looking for the right idea.

share|improve this question
    
This is remarkably similar to gamedev.stackexchange.com/questions/6199/…. –  user744 Mar 5 '11 at 17:25
add comment

3 Answers

up vote 4 down vote accepted

You can perform a spherical projection in a pixel shader applied to a quad.

Assume the sphere is centered in the quad and the projection is orthogonal (it becomes slightly more difficult with perspective projection but if you pass your inverse view and projection matrices within the shader you should manage to do it, too).

Instead of querying the texture coordinates the usual way:

gl_FragColor = texture2D(texture, texCoord);

You use texCoord as the final coordinates of a spherical texture mapping and retrieve the original texture coordinates by reversing the process:

float x = 2.0 * (texCoord.x - 0.5);
float y = 2.0 * (texCoord.y - 0.5);
float r = sqrt(x * x + y * y);

float d = r ? asin(r) / r : 0.0;
float x2 = d * x;
float y2 = d * y;

Now x2 and y2 are values between and π. You need to “scroll” the texture according to your time variable, and normalize your texture coordinates. For a simple rotation around the Y axis:

float x3 = mod(x2 / (4.0 * pi) + 0.5 + time, 1.0f);
float y3 = y2 / (2.0 * pi) + 0.5;

Then finally query the texture, but only if we fall inside the sphere:

if (r <= 1.0)
    gl_FragColor = texture2D(texture, vec2(x3, y3));
else
    ; /* Choose something to do here */
share|improve this answer
    
Just what I was looking for, thanks Sam. –  Olhovsky Mar 6 '11 at 11:56
    
Thanks, your +1 just allowed me to add comments so that I can warn you that I fixed a few issues in the code :-) –  Sam Hocevar Mar 6 '11 at 12:15
add comment

You might find http://www.voofoostudios.com/?p=33 useful.

Note that a sphere towards the edge of the screen won't be represented in 2D by a circle - perspective will distort it a bit.

share|improve this answer
    
I do find that interesting and +1 for the interesting link. However that article mentions nothing about how the mapping of the texture to the circle is done :/ –  Olhovsky Mar 5 '11 at 11:41
1  
They don't go into much detail but it does say: "Texturing is slightly more complicated. We either use a cube map (the simple case), or we have to do a bit of inverse trig in the shader to work out a theta and phi, then map this into UV space." –  Adam Mar 5 '11 at 22:12
add comment

If it doesn't have to be highly accurate, you could write a simple 2D displacement-map filter (something like this pixelbender shader). Then use a 2D normal-map to achieve a spherical effect. Here's an image showing the result (above) and the normal-map (below) [source]:

2d spherical displacement

To give the effect of a rotating sphere, you would simply move the image (checkerboard) and mask it with a circle (or discard all the pixels outside the circle radius).

share|improve this answer
add comment

Your Answer

 
discard

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.