I recently replayed spore in order to review is for my research. Aside from my critical opinion of the game itself (perhaps more on this later) I was particularly intrigued by the procedurally generated worlds that feature most prominently in the ‘space stage’. Having already examined the various methods of generating planetary type spheres (tesellation, long/latitude etc) I had also concluded that for most purposes a cubic sphere approach was the best for extending heightmap based world generation. Essentially this process involves taking a standard 3d cube where each face is a mesh of some specific dimension (64×64 in the case below) and then normalising each point on the face to a vector that we can project outwards to a spherical surface. When such a mesh is fixed around the origin at an appropriate scale, each projection will make a curved surface that is a 6th of the overall sphere. Of cource there is some distortion where the corners of the faces are squashed together, but this is fairly minor, especially when compared to the polar distortions you get with heightsliced spheres. To implement the mesh creation I made a class in unity to handle a single face and then spawned six of them at the appropriate angles in the worldspace.
The next step is to add heightmap displacement to the spherical projection of each point on a face. Its trivial to take a set of 6 heightmap textures and apply them to each face to provide an offset to the projection return vertex.normalized * (radius+heightoffset);. However the main issue to deal with is the seams/cracks between faces. All the neighbouring heightmaps must form continuous values across their borders, and since we are essentially using a cubemap, several borders are rotated or flipped. Initially I considered writing some sort of transformation function to allow my procedural heightmap functions to work across a cubemap. This proved quite difficult and at the same time i discovered that spore (and others) ‘cheats’ by generating a reversed cubemap texture from a clever internal set of cameras and some origin facing billboards.
The approach is to generate an array of billboarded ‘brush’ polygons around the origin of a 3d space. The brushes are mapped with various textures that (alpha)blend together to form terrain heightmap features. The polygons all face inwards and essentially create a reversed sphere of your final mesh. Six camera shots are then taken of the brushes from the location of the origin and along each axis and direction.
Brush polygons arranged in a sphere
Due to the persepctive correction of the rendering process (remember to set the fov angles to 90) the resulting images form a perfect cubemap. These cubemap faces can then be used to displace the points on our actual sphere face meshes.
A different heightmap brush result
There is a unity webplayer demo here . Its just one simple brush and you will need to refresh the page to generate a new sphere.
Next I implemented a height/slope analysis function to create a blend map for assigning different textures per altitude in a seperate shader (see previous posts) and a third person controller/camera. I will post some more detailed images either here or on flickr when I record a larger range of worlds, possibly with atmospheres, specific coloration and water etc.