Open World Terrain Map representing the full area of a spherical (planet) body.

So we have been working on a full open world map system.

First version ended up being a 360* x 180* map system with a 36,000 x 18,000 km world area.

Yes this is BIG, 144GB of Terrain Data to be exact.

We use a dynamically loading terrain chunk system. Which uses custom Asset files to load TerrainData, as well as all environment structures, and NPC spawn points. Each spawn point then loads a NPC from the designated Asset file for that NPC.

v1.0 Cylindrical Mapping System

This is the simplest of ways to translate a Vector2 (x,y) map system to a world map. The main problem being of course is this is a Cylindrical Map System.

Diameter of x in this case 36,000 is maintained at all times while traveling +/-9,000km. This is not Spherical! But the easiest to do.

v2.0 6-sided-cube Mapping System

Next we have moved to Version 2.0 which is a 6-sided-cube Map. We are representing the world a 6 faces each with +/-45* on it in each access. This method of using a six 90* x 90* maps seems the best. But at the same time has some issues of it’s own.

We store the map data in a Vector3 system (x,y,side[0-5]). This works rather well

The main problem is when a player reaches one of the 8 cube points in the world. We are displaying the environment to the user as flat Vector2 Terrain elements. So you need 4 terrain chunks to meet at a point of junction. Which works except at these 8 point. Where you only have 3 terrain chunks available.

Work around so far that we have is to confuse the end user. We do this by creating what I refer to as a deadzone terrain chunk. This area of the world is void of an distinguishable features to the horizon. By doing this you are able to fill in the fourth unavailable terrain chunk with a deadzone chunk as well.

a good example of deadzone chunks would be continuous ocean surface.

One solution is graphically fill in the empty space with a deadzone chunk. And translate the user to the correct piece. But Issues arise when dealing with multiplayer. As player location cross chunks get distorted. As well the effect of the deadzone can also be observed from high altitude flying.

Other option is to preform a distortion to remove the empty area at rendering/runtime. Basically making a 270* area appear to be a 360* area to the user.

v3.0 Instanced 6-sided-cube Mapping System

The third option is to stay with the 6 sides mapping, but instance separate the user from each side. The end user experiences a load screen which masks the change from side to side. but this removes the world map from being truly an open world map. But leaves you with no issues. Typically you would use a mass transit system to move them between sides. And design the surface that no terrain can allow travel from side to side. This would exclude user controlled boats, planes or spacecraft from exiting via a side.

As you can see making a 2D world map is a lot simpler then a full 3D spherical one. As a rectangular area can not be translated into a spherical system with out a lot of pitfalls. Which is why most maps remain a sliced area of a side. and never a full 100% open world.

Please leave any comments or discussions on the technical difficulties of designing around a spherical open world map system here. I will try and watch and respond the thread.

I prefer the v2.0 6-sided-cube system, but yeah, you will need to treat the eight corner points special. This is the system often used in big geospatial models (climate models, etc.) in the scientific community, because it’s easy to work with and minimizes discontinuities. (EDIT: it’s also how KSP does it, IIRC.)

I don’t fully understand the 270° - to 360° issue, though. There is no “missing chunk” if you think of these as faces of a cube. In fact, if you don’t round out the terrain, you could actually play on faces of a cube. Then any place in the world would be showing one (middle of a face), two (edge between two faces), or three (corner) faces.

When you subdivide those faces into smaller chunks, then yeah, you’re going to have four nearby chunks in most places, and only three at a vertex. But those three or four already fit together neatly. (Still imagining playing on a cube.)

Now you just round out the world by normalizing the distance of each ground point from the center. Everything still fits together, no gaps.

1 Like

I have no experience with this type of thing so this is probably naive, but I’m curious why you wouldn’t go for a more sphere-friendly scheme via a UV-style coordinate system.

You both seem to mistaken I am not rendering to a sphere. or to a 2D map image for the user to view.

we are loading Terrain’s with height map data that is viewed by the user in first-person / VR.

We have 144GB of a sphere to 6 sided cubes height data generated. We already have created a cube map sphere for view from outer space of the planet.

But what we have been trying to design around is translating the data to actual in game first person viewed terrain.

We also when in high elevations load via renderTexture the Planet Sphere in to the south-pole of the active sky-box to extend the horizon distance.

@JoeStrout you are correct v2.0 6-sided is best so far. And it allows for 6-sided spheres for rendering the planet as a sphere. For the cardinal coordinates mapping of the player location I can also do this with a 6-side map.

The problem is the pesky 8 corner areas.

We load 2048x2048 terrain chunks with 10km2 each chunk has 8 points of transfer to adjacent ones. 4 sides, 4 points. The world is 36,000km or 18,000km, with 500,000 of 256MB of TerrainChunks. and a surface area 648,000,000 km2. (A combined resolution of 73728000x36864000px). We continuously load the next chunks as needed and we slide the terrain + player + anything else on it back to origin. (to prevent a float error from 7 decimal places in scene.

When we come to the corners of the 6-sides cube we can no longer do this. So long as the user can not visibly see the corner point it’s fine. Such as a edge transfer. But of they decide to say stand at the absolute intersecting point of the three chunks that form the corner. Then rendering can not be done. Since we only have 3x 2048x2048 pieces to work with but would need to load 4 to completely fill the screen as the player rotates through 360*. Which is where the 270* came from.

Ah, I see, the problem here is that you’re using Unity’s Terrain object. It is always square (or rectangular).

Well, let me ask: do you really need to use Unity’s Terrain class? It’s fine for basic uses but tends to fall down when you push it with any unusual case (like this one). This sounds like a pretty major project already — I bet if you gave your engineers a week or two to come up with a replacement, that could handle the odd shapes needed at some points (since there are always odd points somewhere or other on any mapping of a sphere), they’d come up with something.

1 Like

Design wise for creating a continuous open world v1.0 Cylindrical Mapping System is actually the most free of artifact and design issues. 36000km x 18000km world can easy translate to a cardinal coordinates system. as a sphere is +/-180* by +/-90*. We are free from corner artifact. And are only left with the realism issues of the design. Since technically it would take 36000km to travel around in a circle at the north pole. Which obviously is not realistic at all. But functionally if you drive player attention away from those areas unless they are a detail oriented person, they might never notice.

v1.0 Cylindrical Mapping System I still keep leaning to, but the issues with dealing with the corner points is a big one. and causes 8 points of issue verses 2 points of issue in v1.0 Cylindrical Mapping System. The only solution I can think of currently to deal with the corner points in v2.0 is to do end caps.

v2.1 Cylindrical Mapping System with triangular end caps.

v2.1 is the same as v2.0 but triangular end cap tracking of players. What you would do is have the player switched into a end cap terrain. If I express the absolute centre point of that terrain as (0,0,0) that location would be equal to the intersecting point of 3 square faces to a cube. Where that intersect point if (0,0,0). We would then calculate a equal lateral triangle from (0,0,0) on the end cap terrain. With the length of each side equaling the length of the diagonals the target square.

We then translate to player onto and off one of the 3 faces of the cube corner. obviously doing this on ocean is easiest to do. Else you have to distort some height maps.

Ya they came up with v2.1 we render a 60-60-60 equilateral triangle on a 1:1 square terrain. It is subdivided into three 30-30-120 triangles with the With the length of each side equaling the length of the diagonals the target square. Then translate the players as the cross the terminus. Thus making each of the three terrains that make up the corner pieces. Be virtually 3 60-60-60 triangles with one edge translating to 3 30-30-120 triangles. And the remaining two edged going off the the standard 1:1 square chunks.

We will have to eventually test this system out. We basically made three 60-90-120-90 faces areas to make the end caps.

PS. if anyone implement this method don’t forget that when translating the player to the end cap 30-30-120 triangles that the sky box needs to be re-aligned and tracked correctly manually.

1 Like