Here are some things we learned from our experience of designing fast, smooth and efficient chunk-based terrain generator.
Voxel-based games become more and more popular these days. It's not surprising, because voxel-based games allow such things as completely dynamic world and procedural world generation. Also, games made of cubes (e.g. Minecraft) look simple yet pretty.
The most important part of a voxel-based game is world. For our project, "The Traveler", terrain generation is critical because the idea of the game is based on travelling and exploration.
Here are some things we learned from our experience of designing fast, smooth and efficient chunk-based terrain generator. Even though we developed this system a year ago and the game itself now looks completely different, basic principles are the same.
#1: Create a mesh for each chunk
Basically, this is the most valuable thing you need to know. Why? At first, our chunk generation used separate colored cubes for the terrain. Results weren’t that good : about 40 fps with only ~5000 blocks(your results may vary). When our team applied a separate mesh generation for each chunk performance skyrocketed to the amount you see in the title.
How is that done? There is a wonderful tutorial on this matter from this guy. To sum up, what you need is:
- World controller script, which will control the generation, enabling and disabling the chunks.
- Chunk script itself, which will create and hold information about blocks, terrain height(using Perlin noise, supplied with unity or your algorithm of choice), chunks’ mesh and other stuff you will need along the dev process.
- Block script, where you will generate vertices(points of mesh), colors, triangles and apply block’s part of the mesh to chunk’s mesh.
A photo of terrain generated using perlin noise in our game called “The Traveler”.
#2: Make as many things multithreaded as possible
Yes, you may argue that Unity itself is not entirely multithreaded and its’ API is not thread safe, some of the parts of mesh creation can be made in a seprate thread, provided it does not call any Unity API functions.
Why is it important? As I’ve said, Unity does not fully use all of cores of your CPU, so having CPU working on 50% of its power rather than 20% (depends on the number of cores) will considerably boost your performance. Also, you should bear in mind that thread creation itself has some performance overhead, so the benefits of having multiple threads are more clear when using big chunk sizes.
Partly generated terrain which consists of around 3 million blocks.
That's all for now. If you have questions, feel free to leave a comment. Also, if you like voxel-based games, you might want to play "The Traveler". Fortunately, we are starting a closed beta-test soon and you can sign up at our website to get an invite. Have a good day! :)