Friday, November 27, 2015

Procedural Planets

I've started work on the procedural planets, here are some initial screenshots.  Like everything in Pegwars, it all has to be seamless, from flying in outerspace to orbiting planet and moon surfaces to landing and running around.



Each planet's geometry is formed by tessellating an icosahedron.  This shape was chosen to help make each vertex as equidistant as possible in the final mesh; tessellated icosahedra perform better in this regard than tessellated cubes or parametric spheres, and have the added bonus of having triangular faces, making it easy to tessellate and render.

Each triangle face of the icosahedron is recursively split at the edge midpoints to generate the next level of detail of geometry, as needed.  For performance reasons, as you don't want to be allocating GPU resources at runtime, Pegwars has a fixed set of vertex and index buffers for planets and moons - meaning a maximum of 10 planets at once, each with up to 3 orbiting moons.  Once I improve the level of detail algorithms, these restrictions will be able to be lifted.

The surface parameterisation for planet metadata and texture mapping is the cube map.  Each planet has generated for it a cubic height/slope map, texture map, object map and normal map.  Later on I will add cubic sub-surface mineral maps for resource extraction as well.

The reason for generating cube-maps for objects (and later minerals) is that the player will be able to customise any planets they have control over, to terraform, build structures and mine resources.  These will be updated in the underlying cubemaps and persisted to the game save storage.

Currently each planet has 9 levels of detail for the basic tessellation.  This provides decent enough resolution down to planet flight, but not enough to generate a convincing on-surface tessellation.

Because the topology of the planet meshes never changes, one level-of-detail index buffer is generated at startup and reused for every planet and moon.



Procedurally generating the heights for millions of vertices as well as calculating diffuse maps, normal maps and object maps takes a lot of CPU time, it is definitely not a real-time task.  So in order to achieve this during gameplay a brand new multi-core job system was created.

The job system allows arbitrary tasks to be run in the background in parallel across multiple threads; in addition there are 2 dedicated task threads that run on the main (rendering) thread - these are for final DX resource allocation tasks, as well as general main-thread tasks that are amortized over time to avoid frame-rate impact.

When a player travels near enough to a solar system, the background jobs start generating the solar system's planets and moons.  By the time the player travels anywhere near a planet or moon, its levels of detail will have been created, along with all associated cube map metadata.  This allows for seamless traversal from outer-solar-system flight all the way down to the planet surface.




In addition to the planet itself, I've also started work on procedural ground objects.  These objects are generated based on the underlying diffuse map (as the diffuse map for the planet is really just a hack to describe the make up of its actual surface detail), with other inputs such as the slope and relative slope.  I'll also add to this an equatorial value (colder at the poles) and once ocean and river systems are added, proximity to water.





No comments:

Post a Comment