Rendering planets: Distortion free spheres

Many thanks to rdb, craig, thomas, and everyone else active in the chatroom. This is more their code than mine :slight_smile:


Would you believe me if I told you this is really a cube?

Rendering spheres, such has planets, has always been difficult. Traditional spheres and textures results in pinching at the poles and waisted vertexes and texture pixels. All sorts of novel approaches have been developed such as impostors/billboards, iconspheres, and cube mapping. Creating a large sphere with decent LOD remained problematic.

A current popular solution is to take a cube with grid siding and normalize it into a sphere shape. One of the major advantages is that the sides can use standard, conventional terrain LOD techniques such as geomipmapping or geoclipmapping. Texturing is also cube map based allowing for better texture resolution. There is also a proof which will map the sphere so the vertexes are distortion free.

I should note I have not done tested texturing, so the sides may need some rotational help. I welcome any help, bug fixing, optimization, or updating the shaders to opengl 3 land.

Code hosted on gist

I’m working on a similar project; I ended up going the ico-sphere route. I start with a basic 20 sided icosphere and then recursively break it down into a smooth(er) looking sphere:


I’m interested to see the results you get with your technique. What’s your ultimate goal with this? You mention planets, which is essentially what I’m working on, but there are lots of different goals one can have for planets (background, sims, game environment etc.) Ultimately I’m hoping to make something similar to Kerbal space program, but with more emphasis on exploring the actual planet surfaces and environment.

My ultimate goal is to make a genericish space engine I can base my Two Dream Games off of with planets at realistic scales. I’ve been inspired by the photos from the ISS on just how damn beautiful Earth looks from low Earth orbit and videos of the Saturn system from the raw Cassini images. There is also this project of video flying through the saturn system using no 3d models (another longer trailer here).

My big objective is to have good looking planets even at low orbit. The ISS orbits at only 370km (230mi) altitude. While that seems far away it is only about 3% of the diameter of the Earth. So a good LOD system will be needed. While there are methods for a solid sphere (ROAM and others), using a quad sphere allows for more “normal” methods.

While neither of my dream games will require seamless planetary landings I would like to have the ability to plug it in fairly easily.

For reference I’m using a similar method to KSP: kerbalspace.tumblr.com/post/9056 … re-awesome

An icosphere breaks up naturally into panels which can be represented with data grids fairly easily (though the way the borders interact is very counter-intuitive.)

For my own game exploring and manipulating the planets is going to be important so keeping track of (and being able to alter) each vertex is key. Using panels also helps with creating a lod system when placing a LOD node at the center of each panel:

Realistic scales might not achievable. For myself I quickly abandoned the idea of realistic scales when I encountered fact that graphics engines only use single float precision for vertex coordinates which places an effective limit on the size of your world. Let’s say you choose 1 meter as your base unit, this means that as soon as you move beyond 65536 meters (65km which is nothing in space terms) from the origin (0, 0, 0) you lose an entire digit of precision, and then again when you move 10x further than this. The effect ends up being of a ship or character that no longer moves smoothly across the screen but one that jumps around from point to point. For a better explanation see this thread:

[url]precision of coordinates in Panda3D?]

For myself realism isn’t the most important aspect, but play-ability, so in the end I went with a size scale for planet bodies of 1000 to 1, which sounds really small but actually still leaves a lot of surface area (570km**2 for an Earth sized body). Though even at this scale I still had to come up with some elaborate mechanics to get past the precision limitation. Here’s a crude render of a fairly early version, the features are exaggerated and the ocean is simply a blue sphere but it shows the basic idea:

The floating point issue has been solved in a couple different ways already. The first is to keep the camera at 0,0,0 and transform the world around it. The second is to scale down objects as they become more distance. So for example move a planet up to, say 10,000 normally, but if you want to represent a planet 20k away move the mesh to 15000 and scale it down to 75% (or however the math works out).

That’s the solution I took, though for large objects like the Sun I’ve had to employ the second solution as well, but you have obviously looked into all this in depth already. I look forward to seeing your results.

I want to redo the nightside to be a glow map, redo the scattering shader to use the precompute method, and add procedural clouds, and fix the spec glow (it does wierd things).

hmm i tried running example but got this:

DirectStart: Starting the game.
Known pipe types:
  wglGraphicsPipe
(all display modules loaded.)
289
289
289
289
289
289
:display:gsg:glgsg(error): Active attribute p3d_ModelViewProjectionMatrix is bound to location -1
:display:gsg:glgsg(error): Active attribute p3d_ModelViewProjectionMatrix is bound to location -1

Any idea why it would fail?

That’s not an error; that’s a harmless debug message that got accidentally marked as error message.