Skip to main content
gamedev.net
🔒 Locked

Globe textures

Started by tre Jun 28, 2010 at 1:02 PM 4 replies 2.8k views
Original Post
tre
tre
Hi all, I've been here asking questions for some time now.
Those of you who might remember me know that I've been struggling with a globe (and input and a lot of other stuff) in OpenGL.
At the moment I'm trying to move from the old OGL to the new.

However, what I'm here asking today is if anyone's got any ideas for putting textures on a globe.
I've been looking at a lot of different map projections and the one that strikes me as the best would be Robinsons (at least for now). I guess that means that I'll set up my globe texture coordinates so that the correspond to the Robinson Projection.

I've downloaded (or am downloading) the NASA's blue marble next generation set to my computer. 500km/pixel or something like that should give me quite detailed textures. I'm thinking of running them in layers based on how far from the camera the earth is (like all the other globe programs seem to be doing).

I guess it's a quite open question this. If anyone's got any tips or pointers (if you've done anything like this before or are in the same position as I), please just put in your two cents.
I'm interested in all manners of approach to get my globe to look it's best.

I will be adding more effects to my globe as I get the whole thing looking good. I have a shader standing by which changes the texture on the "dark side" with night lights. And I'm trying to figure out how to apply a radial gradient and a glow to my globe's edges.

I'm also trying to figure out how to best do the background stars (textures or self illuminated polygons with a glow shader or something).

So, If you've got any cool ideas on how to proceed, I'd be all ears. I'm alone on this project and am using it to learn and improve my OpenGL skills.

Thank you in advance,
Marcus Axelsson
dsr12
dsr12
I did what you are trying to do a while back (make a globe with satellite images, specular map, night lights, and atmosphere) for the sake of learning opengl too, but not post-3.0 stuff.

Based on your second and third paragraphs, I am left with the impression that you have a misconception about map projections. There is no need for you to choose a preferred map projection because you are taking images of the earth in 2D form (from satellite photographs) and putting them onto a 3D globe. You are essentially taking a map projection and trying to "un-project" it back into its original 3D form.

The map projection you have to work with is already chosen based on your source image. In this case, the projection used in the NASA blue marble images is the equirectangular projection (http://en.wikipedia.org/wiki/Equirectangular_projection). In short, this format means each pixel in the image represents a constant longitudinal and latitudinal distance going horizontally and vertically, respectively. With this information, you should be able to do the math to figure out texture coordinates for your vertices (when I did my globe, I used quad primitives which make the math really easy, but they are deprecated now).

It is worth mentioning that you have to be mindful of the maximum texture size of the graphics cards on which you want to run your program. This means you will have to chop up the massive blue marble image into manageable pieces. Also you might want to look into texture compression because it isn't too hard to do. It reduces the memory size of your textures and can speed up rendering.

You mentioned wanting to have textures of different levels of details. I'm not sure what your intention is here. Are you familiar with mipmaps or do you mean something like google earth (which shows low-resolution substitute images until the higher resolution images are downloaded)? For stars, I just rendered a bunch of point primitives at random locations and brightness, which looked pretty good to me. You have to play around with the distribution of star brightness to make it seem realistic though. For the atmosphere glow, see http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html. If you are serious about it, do a search for academic papers on rendering atmospheric scattering. There are some good ones from the 90s.
tre
tre
Just the kind of post I was looking for! Thanks.

Quote:
Original post by dsr12
The map projection you have to work with is already chosen based on your source image. In this case, the projection used in the NASA blue marble images is the equirectangular projection (http://en.wikipedia.org/wiki/Equirectangular_projection). In short, this format means each pixel in the image represents a constant longitudinal and latitudinal distance going horizontally and vertically, respectively. With this information, you should be able to do the math to figure out texture coordinates for your vertices (when I did my globe, I used quad primitives which make the math really easy, but they are deprecated now).

I have been thinking a lot about this and I think I'm on to the same course that you were. Split the globe up into several regions and texture those region Texture ID:s with the (veryveryvery) high resolution images from NASA:s blue marble.
I will be trying to create a compability context with OGL3.x so that I won't become overwhelmed (I'm moving from OGL 2).
The way I thought about doing this is to create a globe in a 3D modelling suite, adding texture coordinates and whatever. Exporting it as an OBJ and read that into my program. I've allready got a (pretty shoddy) OBJ-reader that I will be optimizing as I go on.
That way I should be able to be a bit more "artistic" that if I would do this completely by code.

Quote:
It is worth mentioning that you have to be mindful of the maximum texture size of the graphics cards on which you want to run your program. This means you will have to chop up the massive blue marble image into manageable pieces. Also you might want to look into texture compression because it isn't too hard to do. It reduces the memory size of your textures and can speed up rendering.

I will be focusing this first setup on my own gaming rig and from there I'll be scaling down and customizing to get it to work on older computers. However, I will still be cutting up the textures just as you point out.
I will also not be loading the PNG:s that I got from NASA:s web, but rather either DDS or TGA. I guess DDS is the way to go today. Just don't know how to write a reader for that format yet :)

Quote:
You mentioned wanting to have textures of different levels of details. I'm not sure what your intention is here. Are you familiar with mipmaps or do you mean something like google earth (which shows low-resolution substitute images until the higher resolution images are downloaded)?

I was interested in doing the same thing Google Earth is doing. However it does seem like a waste of processing power, switching between different textures at runtime.
Mipmaps is something I've been playing around with and that's the direction I'm most probably moving in.

Quote:
For stars, I just rendered a bunch of point primitives at random locations and brightness, which looked pretty good to me. You have to play around with the distribution of star brightness to make it seem realistic though. For the atmosphere glow, see http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html. If you are serious about it, do a search for academic papers on rendering atmospheric scattering. There are some good ones from the 90s.

That's a great idea for doing the stars. With some sort of glow shader on the vertices I'd probably be able to make them blink and shift slightly in colour and so on. That's something I'll be looking into further.

Thanks for the link to the atmospheric glow. I'm not really looking to create a super realistic atmospheric scattering shader, but I am looking for some way to create a really good looking effect at least somewhat similar.

Something else I've been thinking of are the clouds.
This globe I'm creating won't have a super realistic surface and the camera will not be able to go below the cloud surface so super realistic clouds isn't really necessary either.
I am thinking of doing some sort of noise function (with a bump map) that is generating clouds on the globe. I've been looking at Perlin Noise for this. I was thinking of creating several planes on the globe that contains different generated noise clouds that move to a random spot on the planet (and fades as it moves and changes), when the plane has an opacity of 0.0 and has reached it's destination that plane would be destroyed and a new one would be generated.
Now I'm thinking of maybe creating a new sphere on top of the old and just generate a big perlin noise function that is constantly moving and changing.

This became very long.
Thanks for taking the time to read and comment!
Marcus Axelsson
Mathucub
Mathucub
Here is some code that I used to build spheres.
It takes the size you want it and many divisions.
It gives your normals for lighting, and smoothly
interpolates texture coordinates from top to bottom,
and wrapping around.

It makes the globe as faces of triangle strips. You'll just need
to mock up your own MeshBuilder that stores your vertex
values.

Enjoy!

  private void BuildSphere(ref MeshBuilder Builder,                             float fRadius,                             int iStacks,                             int iSlices)    {        Vector4 Normal;        float r, x, y, z, u, v;        long count = 0;                if (Builder != null &&         fRadius != 0 &&         iStacks != 0 &&         iSlices != 0)        {            for (long j = iStacks - 1; j >= 0; j--)            {                Builder.AddFace(TRIANGLESTRIP);                for (long i = iSlices + 1; i > 0; i--)                {                    for (long k = 0; k < 2; k++)                    {                        y = fRadius * (float)Math.Cos((j + k) * Math.PI / iStacks);                        r = fRadius * (float)Math.Sin((j + k) * Math.PI / iStacks);                        x = r * (float)Math.Cos(i * 2 * Math.PI / iSlices);                        z = r * (float)Math.Sin(i * 2 * Math.PI / iSlices);                        Normal.X = x;                        Normal.Y = y;                        Normal.Z = z;                        Normal.W = 0;                        Normal.Normalize();                        u = (float)(i - 1) / (float)(iSlices);                        v = (float)(j + k) / (float)(iStacks);                        Builder.AddVertex(x, y, z);                        Builder.AddNormal(Normal.X, Normal.Y, Normal.Z);                        Builder.AddTexture(u, v);                        count++;                    } // k                } // i - slices            } // j  - stacks        }     }
Mathucub
Mathucub
Quote:
Original post by Mathucub
Here is some code that I used to build spheres.
It takes the size you want it and many divisions.
It gives your normals for lighting, and smoothly
interpolates texture coordinates from top to bottom,
and wrapping around.

It makes the globe as faces of triangle strips. You'll just need
to mock up your own MeshBuilder that stores your vertex
values.

Enjoy!

  private void BuildSphere(ref MeshBuilder Builder,                             float fRadius,                             int iStacks,                             int iSlices)    {        Vector4 Normal;        float r, x, y, z, u, v;        long count = 0;                if (Builder != null &&         fRadius != 0 &&         iStacks != 0 &&         iSlices != 0)        {            for (long j = iStacks - 1; j >= 0; j--)            {                Builder.AddFace(TRIANGLESTRIP);                for (long i = iSlices + 1; i > 0; i--)                {                    for (long k = 0; k < 2; k++)                    {                        y = fRadius * (float)Math.Cos((j + k) * Math.PI / iStacks);                        r = fRadius * (float)Math.Sin((j + k) * Math.PI / iStacks);                        x = r * (float)Math.Cos(i * 2 * Math.PI / iSlices);                        z = r * (float)Math.Sin(i * 2 * Math.PI / iSlices);                        Normal.X = x;                        Normal.Y = y;                        Normal.Z = z;                        Normal.W = 0;                        Normal.Normalize();                        u = (float)(i - 1) / (float)(iSlices);                        v = (float)(j + k) / (float)(iStacks);                        Builder.AddVertex(x, y, z);                        Builder.AddNormal(Normal.X, Normal.Y, Normal.Z);                        Builder.AddTexture(u, v);                        count++;                    } // k                } // i - slices            } // j  - stacks        }     }


You will have to switch your windings if you are in GL.
This is DX9 code.
tre
tre
Thank you for sharing!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.