4
\$\begingroup\$

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.

\$\endgroup\$
1

3 Answers 3

10
\$\begingroup\$

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 */
\$\endgroup\$
1
  • \$\begingroup\$ Thanks, your +1 just allowed me to add comments so that I can warn you that I fixed a few issues in the code :-) \$\endgroup\$ Mar 6, 2011 at 12:15
2
\$\begingroup\$

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).

\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ 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 :/ \$\endgroup\$
    – Olhovsky
    Mar 5, 2011 at 11:41
  • 1
    \$\begingroup\$ 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." \$\endgroup\$
    – Adam
    Mar 5, 2011 at 22:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .