Jump to content
  • Advertisement
Sign in to follow this  
Toastmastern

Icosphere and height map

This topic is 669 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,
 
After doing some research without finding any good tutorials and only hints on how to proceed with my height map for a icosphere I started working on my own idea and this is what I came up with:
 
1. Take a image of the planet in question in greyscale and import it to a 2D array. I found a large HD image from NASA with a 8192x4096 pixels.
 
2. Calculate Longitude and Latitude for every vertex in my Icosphere, I started with 7 division but will try 8 divisons later on for more details.
Here is my code for getting my hand on Long and Lat cordinates.

float r = sqrtf(mPlanetMesh.vertices[i].position.x * mPlanetMesh.vertices[i].position.x + mPlanetMesh.vertices[i].position.y * mPlanetMesh.vertices[i].position.y + mPlanetMesh.vertices[i].position.z * mPlanetMesh.vertices[i].position.z);

float longitude = fmodf((270 + (atan2f(mPlanetMesh.vertices[i].position.x, mPlanetMesh.vertices[i].position.z)) * 180 / M_PI), 360.0f) - 180;

float latitude = (90 - acosf(mPlanetMesh.vertices[i].position.y / r) * (180 / M_PI));

This does give me values for Long between -180 and 180 and for Lat between -90 and 90. But I don't know if the calculations are correct.

3. Use this Long and Lat value to get the correct Pixel:
 

mHeightMap[(int)((180 + longitude) * (8192 / 360))][(int)((90 - latitude) * (4096 / 180))])

Again I am not sure this will work for my image to get the correct values.

4. Calculate the normals for every vertex:
 

mPlanetMesh.vertices[i].normal.x = cosf(latitude * (M_PI / 180)) * cosf(longitude * (M_PI / 180));

mPlanetMesh.vertices[i].normal.y = cosf(latitude * (M_PI / 180)) * sinf(longitude * (M_PI / 180));

mPlanetMesh.vertices[i].normal.z = sinf(latitude * (M_PI / 180));

Once again I am not sure this calculations are correct since they are depending on both that they are correct by themself but also that the Long and Lat calculations are correct.

5. Multiply the normal vector with the height vector(the height vector have of course been recalculated to represent values betweeen the lowest and highest point on the planet)

6. Add the multiplied vector to the vertex.

7. Render

Now on 7 divisions I get something that looks like a landscape even tho the details is very low and it looks kinda crapy in general. On 8 divisions I get a lot off lines going through the middle of the planet for some reason.
My plan was to make sure the calculations are correct before going into detail of what might be the problem there. The caluclations might solve it(It should atleast since without the calculations the sphere looks like a spehere.)

I might be approaching this from the wrong direction and it might be a easier way to solve this. please enligthen me if thats the case :)

 

Best regards and thanks in advance

Toastmastern

Share this post


Link to post
Share on other sites
Advertisement

A few observations:

1. Do you really need to compute the radius each time? Isn't it a known quantity?

2. Why are you converting every angle to degrees? That's useless and you then have to convert them back to radians (or other range) to be able to use them.

3. The normal of each vertex is the vertex itself normalized. You can thus simply multiply the vector by some value to get the displaced one. If the vector has lenght R and you want its height to be H, you simply have to multiply by H/R.

4. This is probably all best done in a shader. The base displacement can be done in a vertex shader and you can probably also use a tessellation shader to increase details when needed. Finally lighting can do a great work in adding details.

5. I still have to check the correctness of your formulas.

Share this post


Link to post
Share on other sites

A few observations:
1. Do you really need to compute the radius each time? Isn't it a known quantity?
2. Why are you converting every angle to degrees? That's useless and you then have to convert them back to radians (or other range) to be able to use them.
3. The normal of each vertex is the vertex itself normalized. You can thus simply multiply the vector by some value to get the displaced one. If the vector has lenght R and you want its height to be H, you simply have to multiply by H/R.
4. This is probably all best done in a shader. The base displacement can be done in a vertex shader and you can probably also use a tessellation shader to increase details when needed. Finally lighting can do a great work in adding details.
5. I still have to check the correctness of your formulas.

 
Thanks for your replies and to taken the time to look at my code. After rethinking some parts I realized some things
 
for example as you say, the radius is known and is now a constant instead which isn't recalculated each time.
 
The normal vector is so much more simple then I first realized the calculation now looks like:
mPlanetMesh.vertices[i].normal.x = mPlanetMesh.vertices[i].position.x / PLANETRADIUS;
mPlanetMesh.vertices[i].normal.y = mPlanetMesh.vertices[i].position.y / PLANETRADIUS;
mPlanetMesh.vertices[i].normal.z = mPlanetMesh.vertices[i].position.z / PLANETRADIUS;
The Long Lat calc now looks like this:
float longitude = atan2f(mPlanetMesh.vertices[i].position.z, mPlanetMesh.vertices[i].position.x) * (180 / M_PI);
		float latitude = 90 - (acosf(mPlanetMesh.vertices[i].position.y/ PLANETRADIUS) * (180 / M_PI));
and as you say the calc to pi is not needed but I did as well to make it easier in my head for now :)

Also another error was the input from the bmp file was totaly off but after starting to use CImg it works flawless.

The details are still abit meh but I don't think I need to use 8 division to increase that number. I bet it is possible to use my height map in the shader to use the tessellation to increase the details? Right now the tessellation just splits up my triangles which doesnt increase the details. Am I right or? any pointers to where I could find some information on how to do that?

//Toastmastern Edited by Toastmastern

Share this post


Link to post
Share on other sites

In the shader you can do many different things to improve the details:

1. Increase the tessellation dynamically using the tessellation shader,

2. Use displacement mapping to give the impression of details without actually adding more geometry.

Share this post


Link to post
Share on other sites

In the shader you can do many different things to improve the details:

1. Increase the tessellation dynamically using the tessellation shader,

2. Use displacement mapping to give the impression of details without actually adding more geometry.

 

Right now I am working on a plan so that all new vertices created by the tessellation shader also get individual height points. Displacement mapping is something I plan to look into at a later stage the same with dynamic tessellation(by this you might mean what I am currently doing right now, I'm not sure :) ). Right now I have the tessellation amount bound to the players altitude above the planet, any other way to do this that is smarter?

 

//Toastmastern

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!