Simple Planet Texture Generation 02

In this article series we are going to discuss the creation of a simple planet texture generator that will allow us to texture a three dimensional sphere.

In the first short article we started by looking at building a sphere out of a textured box. In this, the second article, we are going to create a height map generator using simplex noise. In the last we will be taking the height map and colouring it according to some simple rules to give the visual effect of a planet seen from space. I'm going to use C# and keep it as straight forward as possible so that it can be easily ported to other languages.

The Heights
What is a height map? There are a lot of resources online that can explain it, wiki, but put into context of how we are going to use it: a height map is a two dimensional image with each pixel's alpha or RGB value representing a height of the terrain at a corresponding position.
What we are aiming for is this:

Continued below....


Each square on this cross-shaped height map represents a face on the the spherical-cube that we talked about in the previous article.
This is all good and well but how are we going to create a seamless height map for a three dimensional cube? By using 3D simplex noise and representing each face of the cube as a plane we create a small height maps for each. Since we now know the spherical position for one plane we can derive the positions for the other five planes simply by switching the x, y and z values. The structure to hold the faces are very simple, we basically just create six height maps which are byte arrays, we then populate them then stitch them together to form that final height map.

Here is the code to generate the height maps for each face, I'll link the simplex noise library I used at the end. The code is the bones of the planet generator and we'll handle the meat in the next article. There are a lot of comments in there so please feel free to read them if you do not understand. Try these base values in the "GetComplexNoise" function and then substitute your own:
  • - frequency = 28.0
  • - elevation = 4.0
  • - roughness = 1.75
  • - detail = 0.5
  • - normalization = 30.0

Ok so now we have six buffers/height maps so all we have to do now is copy them into the destination height map buffer at the right location where we mapped the faces texture coordinates and so we have something like this, use the uvTest.png file I linked in the previous article as a reference:


As you can see if you look close there are some artefacts at the edges of the faces, this is caused by WPFs 3D implementation no having a clamping texture function but it does show off how the faces are mapped.

So now we have a height map to work from, in the next article we'll look at how to add some colour.

Files:
SimplexNoise

PS. Please note this is my first set of articles so please leave suggestions in the comments, also if you find parts of this article that you could improve upon please share with us, this would make it worthwhile for me to have written this as well as contribute to everyone's learning. :)


1 comments:

Smith Allen said...

I'm making a game with my friend that involves randomly generating planets based on certain properties. Originally this game was all 2D, but now we've decided to enhance the purpose of planets in the game and make it 2.5D, with planets being rendered as 3D spheres in an otherwise 2D world. Now, up to this point we had a pretty good thing going with the way planets looked. We used layered textures, one for each property (water, land, atmosphere) depending on how our algorithms created the planet. This looked pretty, but the planet surfaces were largely lame and didn't vary as they were all made from the same few textures.

Now that we are going 3D, I want to create a nice planetary map which will determine the topography of the planet based on its properties to make each planet have different bodies of water, land masses, etc. I also want to draw different textures on the surface of the planet based on that map, with them blending together at the edges.

I've considered two possibilities: rendering the textures based on the map to a RenderTarget and then wrapping that RenderTarget around my sphere model, or converting the map to vertex data and writing a shader to draw the textures with the proper weight.

The problem is, I'm a novice at both RenderTargets and HLSL (as a matter of fact, I don't even know if the RenderTarget method is possible), so I feel the need for some guidance here. What would be recommended for rendering multiple textures to a sphere model based on a generated terrain map? Also, are there any suggestions for what format to create the terrain map in (it would be some sort of data structure which would represent the type of terrain at any coordinate on the planet's surface)?

I have looked at other multi-texture tutorials, but they all seem based on a pre-determined texture or set of values. I need to be able to randomly generate the terrain in-game.
java barcode generator