World Management & Terrain – Part 2

In this update, I’ll show how terrain is generated by Deep Engine and cover topics like heightmaps, texturing, and physics.

Summary

In this update, I’ll show how terrain is generated by Deep Engine and cover topics like heightmaps, texturing, and physics. Now things have progressed beyond the dry theory of Part 1, I can include more screenshots and examples.

Terrain Stamper

Terrains in Project Arroa: Revenwood are constructed with heightmap stamps in a similar way to blending layers together in a paint package. This enables a completely non-destructive workflow for creating rich environments with natural-looking details. Heightmap stamps can be produced with tools like WorldMachine and Gaea, or sourced from real environments.

Stamps can be scaled, translated, rotated, and blended using standard methods like additive, subtractive, multiply, and so on. They can be grouped together and reordered within the layer stack. Deep Engine processes all of this using fast compute shaders so that a world map’s heightmap is produced effectively in real-time.

Following is an example of two terrain stamps merged together with additive blending, creating a whole new terrain.

Other than generating large-scale natural terrain features very quickly, stamps can also be used to refine terrain in a smaller area, such as flattening out landscape for a town. In the future, stamps will be augmented with manual painting/sculpting of terrain for that final touch.

Preparing To Render

Before rendering, the final heightmap output is transformed into a normal map. This map determines the direction each height sample is facing relative to the flat plane, essential for lighting and other tasks. Deep Engine produces this with another compute shader at the end of stamping layout stage. Following image shows how the raw image data is transformed into a normal map.

After producing the normal map, Deep Engine also exports the final heightmap and some other data out to arrays in memory for CPU-based processes. With everything ready to go, the pipeline can move on to layout out terrain tiles in world space.

Terrain Clipmaps

Deep Engine uses a geometry clipmap approach to render terrain efficiently based on distance from viewer. The world map is chunked into terrain tiles of 512 x 512 metres each, which in turn are subdivided into patches of 128 x 128 metres each (so 4×4 patches per terrain).

As viewpoint camera (e.g. the player) moves around scene, the most appropriate patch is decided based on distance. This forms a square grid of terrain tiles around viewer with descending levels of detail. In this way, only the terrain near viewer has a high level of detail and will become less detailed (so more efficient to render) farther away.

Visualised as a wireframe, the clipmap grid looks as below. At the centre of concentric rings is the highest level of detail centred on player position. Then each ring decreases by one LOD level until the coarsest level of detail is reached. Click on image for higher resolution.

If you look carefully, you’ll notice that at every boundary from one LOD to another, the triangle fans get larger to match the spacing of adjacent LOD. This ensures there are no gaps between tiles.

This grid will continuously update layout as viewer moves so terrain is only rendering as much detail as needed.

Rendering Elevations

With all of this in place, Deep Engine is set to render terrain elevations. This is performed entirely on the GPU vertex shader by passing in the heightmap prepared earlier. Every vertex samples the heightmap and moves the vertex upward based on elevation height and terrain scale. This results in our heightmap deforming the grid above to create all of the bumps and hills to make an actual terrain!

Because clipmap patches reduce the number of vertices as distance increases, the vertex shader producing this terrain is very efficient and only moving vertices visible to player.

Texturing Terrain

The next thing Deep Engine needs to do is apply more natural-looking textures. This is accomplished in the fragment shader with a texture array and control map containing parameters for steepness threshold and scale. Then for each sample position across terrain, any two textures are sampled from array and blended together based on control parameters. This allows for large-scale convincing vistas to be generated automatically then fine-tuned with hand-painting. For example, a town will have hand-painted paths and other details.

To demonstrate this more visually, here’s the terrain rendered with a uniform stone and grass texture without any modification by control texture.

With control texture parameters, the two textures can be combined based on the steepness of terrain.

This is still really flat however. This is because the terrain is not interacting with scene lighting. If you recall the normal map produced earlier, this can be input into fragment shader so that terrain is lit correctly. This goes a long way to producing a more convincing-looking environment.

By combining different textures together with different control parameters, the terrain can be textured automatically in a variety of ways.

This is still very early in development, but should help demonstrate the potential of the terrain system.

Terrain Physics

Terrain is not very useful if the player and other key actors are incapable of moving around on its surface. For this, Deep Engine also needs to generate a static terrain collider.

If you recall from earlier, the final stage of building terrain heightmap is to export some of the GPU-generated data back into memory for the CPU. This is required as the physics system operates entirely on CPU and must be provided collider shapes matching the intended physical surface.

Using this exported data, the terrain object will generate a list of triangles that are handed over to the physics system as a static mesh collider. In following screenshot, the collision mesh is shown overlaid on top of the visible terrain. For efficiency, the collision mesh is generated with a lower sampling frequency.

Note the collider is at a continuous level of detail and there are some points where the collidable terrain does not perfectly match the visual terrain due to sampling differences between the two systems. I have a refinement for this in the works using error maps to determine where more precision is needed and insert higher-LOD physics patches as required. But even this simplified terrain collider works surprisingly well as the errors mainly accumulate in steep parts of terrain that are not typically walkable.

The entire process of generating collider on CPU is multithreaded and very fast, and has no impact on performance as player moves around the world. While this is not quite where I need it to be in terms of accuracy, it’s close enough that I can continue making progress and refine further over time.

To better demonstrate physics in action, here’s a clip where I’m spawning what I call physics confetti and following it as it rolls and tumbles downhill.

Deep Engine Editor

Project Arroa: Revenwood is intended not only to be a game but a tool for creative modding. To make this possible, Deep Engine will ship its editor built directly into the runtime, not as a separate tool. With one keypress, you can pause the live game and break into a desktop-quality engine editor to inspect game state and open a variety of tools for creating new maps, quests, and much more.

The editor interface is very lightweight and has zero overhead when not open. I believe the ability to instantly move back and forth between the live game and editor tools will create a rapid workflow for building mods. In addition to GUI-based tools, the editor includes a console where commands can be issued directly into the engine at runtime to aid with debugging and development of mods.

This is still very early in development and will progress greatly in time. I’ll show more of this tool as it evolves, for now just keep it in mind as core pillar of the project.

Conclusion

I hope you found this update interesting! There is a part 3 of this series in the works, but it won’t be finished for a little while. Now that I have a functioning terrain system with physics, I’m keen to do something along the lines of prototyping environments and gameplay next. I’ve been working on terrain for a solid few months and it will be nice to take a break and work on something different for now.


Posted

in

by

Tags: