Dev notes: Creating Worlds, pt. 2

In the first part I explained the difference between an “endless plane” flat procedural world and a planet-type one.

We’ll start with a spherical body with uniform surface details. As the camera gets closer to the surface, more details appear, until we’ve “landed” on the planet, at which point things should look about the same as with a flat world.

There are two important ideas to this. One, the spherical body will be based on an extruded cube, which means that the “one threedimensional body” challenge will actually be a “six slightly curved planes” challenge, and thus much easier to solve.

cupesphere

extrudedquad

Two, our “endless plane” procedural world will become a “finite plane” with defined corners. In order to zoom out and view the entire planet, this plane must be able to be rendered as a whole (no cutting off and appending stuff as we go along). But it must also support multiple levels of detail, up to the point where the camera can be put right on the surface to show small terrain details.

Generating the grid

On the endless plane, our LOD grids always had the same shape, and we kept them centered below the camera by cutting the far pieces off and appending them to the near end. On the finite plane, we’re going to move the LOD grids around instead.

plane_simple2 finiteLOD

And this is how it’s done. Start with a single quad that consists of a x*x grid (4*4 in this case). Test which parts of the grid are directly below the camera. This grid part of the quad won’t be rendered (shown in red on the image below). Instead, fit a smaller 4*4 quad into the resulting hole. Repeat until the desired level of detail is achieved.

finiteLOD2

Ok, but when the camera is right on the edge of a quad, there’ll be a lot of detail on the one side and less on the other, and that’ll look stupid. So let’s increase the LOD on all the surrounding grid parts as well. That way, whichever way you look, the edge where the detail drops off will always be at least one subquad away.

That means that we’ll need to test each subquad if it’s right below the camera, or if it’s next to the one below the camera.

The way to do this is basically: This is a quad, here are its 4*4 subquads. The camera is over there, and we want to put 9 subquads below and around it. Is any of these 9 also one of the 16 subquads of the original quad? Then cut a hole and replace it with a higher resolution quad. Repeat this check for every quad.

You’ll end up with something like this. As you can see, the camera is surrounded by high resolution subquads, even if they’re part of a different quad that the camera isn’t touching.

camquads

On a sidenote, what’s a good way to decide on how many LOD layers to generate? We do know the camera distance from the surface.

You could write a complicated algorithm to determine the LOD count, but I’ve found that the easiest way is to use a lookup table and experiment a bit until you’ve found values that look good. Even for a planet with the size of Earth, you’re only going to end up with 20 LOD layers or so.

Rendering

Now it’s time for a first attempt to render our new plane! We’ll use a simple terrain algorithm, compute the normals and do some basic shading.

render01

Next step, fill in those nasty gaps between the different LOD layers.

render02

For the next screenshots, I’ve increased the grid resolution from 4*4 to 8*8 and added some normal smoothing, so there’s no more hard edge between the shadows.

render03

render04

render05

And this is what the quad looks like from above, with all LOD layers enabled. There are actually 8 levels of detail, but they quickly become so small that you can only recognize the top 4. It’s obvious that you would only want to have 1-2 detail layers from this camera perspective to prevent the “high resolution island” effect.

render06

That will have to do for now. It would sure be fun to continue with rendering textures and planting some grass. But first, we’ll have to turn this into an actual sphere.

To be continued…

by