I am using a standard heightmapped procedural terrain in my project. However, I want the terrain to appear spherical when the user zooms out. This is an attempt to simulate the appearance of a spherical planet. Here is my current algorithm:

        //get the direction from the "planet" center to this vert
        Vector3 sphereCentertoVertPosition = vert.Position - SphereCenter;

        //our rotation axis is the cross between the direction from this vert to the planet center and the root (center of the terrain) to the planet center
        RotationAxis = Vector3.Cross(sphereCentertoVertPosition, sphereCenterToRootPosition);

        //the amount we rotate is based on the distance of this vert from the center of the terrain
        Vector3 fromCenter = vert.Position - Root.Position;
        float amount = (fromCenter.Length() / ((myTextureWidth / Scale) / 2)) * (float)Math.PI;

        Quaternion rot = Quaternion.CreateFromAxisAngle(RotationAxis, amount);

        Vector3.Transform(ref vert.Position, ref rot, out vert.Position);

My main concern is that the rotation axis is not correct. Theoretically, should it be the cross between the vert-to-planet-center and the terrain-center-to-planet-center?

  • \$\begingroup\$ What kind of result is this producing? \$\endgroup\$
    – House
    Commented Dec 18, 2011 at 6:54
  • 1
    \$\begingroup\$ In case anyone googles this, there were three problems. First, the rotation axis should be Vector3.Cross(vert.Position - Root.Position, Vector3.Up); And second, Vector3.Transform will rotate around the origin. To rotate around the heightmap center, you need to subtract Root.Position, transform, and add Root.Position back. Third, you should only rotate PI/4 radians at the farthest points. \$\endgroup\$
    – khayman218
    Commented Dec 19, 2011 at 17:40

1 Answer 1


Hmm, I'm not so sure about rotating the vertices. Perhaps this is not the answer you're looking for, but I can suggest an alternate method.

I've done something similar with maps in my game. I wrote a shader to wrap terrain into a sphere, but it can easily be done outside the graphics card too. It's as simple as mapping the Cartesian coordinates to spherical coordinates. The code would look something like:

public static Vector3f MapToSphere(Vector3f coords, WorldMap MAP) {
    float pi = 3.14159265f;
    float thetaDelta = ((2 * pi) / (MAP.XSize - 1));
    float phiDelta = ((pi) / (MAP.ZSize - .5f));
    float RadiusBase = ((MAP.XSize) / pi / 2f);
    float theta = (coords.z * thetaDelta);
    float phi = (coords.x * phiDelta);

    //Limit the map to half a sphere
    if(theta > pi) {theta = theta - (pi);}

    if(theta < 0.0)    {theta = theta + (pi);}

    if (phi > 2*pi) {phi = phi - (2*pi);}

    if (phi < 0.0) {phi = phi + (2*pi);}

    Vector3f coords2 = new Vector3f();
    coords2.x = (float) (((RadiusBase) * Math.sin(theta) * Math.cos(phi)) + MAP.XSize / 2f);
    coords2.y = (float) ((RadiusBase) * Math.sin(theta) * Math.sin(phi));
    coords2.z = (float) (((RadiusBase) * Math.cos(theta)) + MAP.ZSize / 2f);
    return coords2;

This maybe "too spherical" for you. If so, you can try padding the edges of your map so that the portion turned into a sphere only represents a portion of the surface of the sphere.

Below is an example of the spherical mapping results.

A "flat" map:

enter image description here

And a spherical world, created by wrapping the vertices into a sphere:

enter image description here

Note that there will be a large amount of distortion at the poles if you don't follow the suggestion above to limit the surface area of the sphere this map is stretched over.


You must log in to answer this question.

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