[Tutorial] c# voxel terrain with infinite terrain, saving and loading

Hello game developers, I’ve written a tutorial in c# on creating voxel terrain that can be generated infinitely and saved and loaded wherever needed. Voxel terrain was made hugely popular by MineCraft and I think that’s just fantastic because there’s just so much you an do with infinite, destructible, buildable terrain so I encourage as many people as possible to try making something with voxels. I’ve been tinkering with voxel terrain in unity for a long time now and I think I have a solid grasp on developing voxels in unity.

You may remember or have followed my last tutorial on voxel terrain which got fairly popular, I’ve decided to take what I learned from that and write a new tutorial that’s slightly more advanced and includes more extendibility so that you could use the finished product without starting over to start a game.
I’ve been trying to include the things people requested into the foundation of this tutorial so that we can support the biggest requests in the base tutorial or without big structural changes and I’ve made sure to pack up the assets folder at the end of every part so that in case of problems you can check against a working copy. I’ve also made the blocks into their own classes so that it’s really simple to add new blocks with completely different looks and functions.

So far I’ve written six parts in which we’ll create the base structure that lets us create as many chunks as we would like in any direction and save and load chunks as we please. I’m planning more specific use tutorials covering the less essential parts for later. See the tutorial here: AlexStv.com Voxel tutorial

Here are some pictures of the project after part 6 where we add terrain generation:

If you’re interested check out the tutorial on my website here: AlexStv.com

12 Likes

Love your tutorials! Would you consider doing something like a marching cubes tutorial or smoother terrain once you’ve completed this set?

The next part is in progress, I’ve been working on adding ambient occlusion to the mesh data in my own work so I thought I’d make it into the 7th part of the tutorial. Ambient occlusion adds shading in the corners of the mesh where one block meets another, unity pro has a built in AO screen effect but what we’ll implement adds it as part of the vertex colors of the mesh and works in unity free. It makes it a lot easier to see the terrain clearly:

See before and after here: http://imgur.com/a/i3rhJ#0

I’m considering it because so many people have said they would be interested but it will probably have to wait until I have a lot more of this tutorial done.

Completely understand, Eagerly awaiting the rest of them. :slight_smile: The ambient oocclusion looks awesome btw (:

Awesome tutorial and awesome update, looks interesting. What do you have planned to add to the tutorial? Are you going to go into greedy block rendering, or just stick to what you are using now? The greedy rendering looks pretty slick and cuts down on FPS from what I’ve read.

Thank you for this tutorial, it’s really helped me get going!

Hi!

First of all: Very nice tutorial. I have a lot of respect for you, spending so much time to create this detailed tutorials.
I’ve benn working with voxels in Unity for quiet a while now and back then when I started I would have loved to find a tutorial like this.
I’ve just downloaded the scripts from part 6 to compare your engine to mine and I actually found the same “problems”.
Updating the chunk will push up the Main Thread time from around 13-14ms to 17-18ms (at least on my computer), which becomes noticeable with a small lag. Also your chunks are very small. 16x16 blocks is really not much, but I am aware of Unity’s verts limit so there is nothing you can really do about it.

From what I know there are three optimisations you could do:

  • Greedy meshing (at least for the collision mesh, but actually I have no idea how to propely implement this :smile:)
  • Threading (very anoying thing to do with Unity but it is possible)
  • Jagged arrays (Block[ ][ ][ ] instead of Block[,] however not really that much of a performance boost)

I am currently looking forward to a voxel package that will be released on the Unity Assetstore that looks really promising. I might be able to learn some new things about voxels in Unity from it. We’ll see :wink:

Sorry for my English
Wizz

He said something in the tutorial about changing the chunk size to 32x32 i believe (:

Part 7 is released: It loads chunks around the player as they move!

I have some ambient occlusion code for a part in the tutorial and eventually I have an implementation of water I’ll include but I haven’t planned much else or what order to do things in. Greedy meshing really is cool but I haven’t actually tried implementing it, I might look at it in the future.

Yeah I would like to get chunks loading faster but I don’t really want to dive into threading and jagged arrays in the tutorial. another thing is that the object oriented approach to blocks adds a bit of overhead but I think it’s worth it for the extendibility. I can see how greedy meshing on the collision mesh would speed things up so maybe I will look into it.

Awesome! I enjoy watching my terrain load as I fly around, its pretty cool. I think water and trees would be a good next step, as it would bring some life to the world!

I hope ambient occlusion comes next as well, just to help with the lighting a bit. Do you have any plans to look into more advanced terrain loading, such as biomes and seas etc?

Your series is amazing so far!

1 Like

This series is really good! I’m planning to make a similar 2D engine, so I’ll try making some changes and see if it works :smile:

Great tutorial! One thing I am curious about is how to allow the block textures to be spread over multiple image files?

Nice tutorial, but I’m getting this error after the part 3:

NullReferenceException: Object reference not set to an instance of an object
Chunk.UpdateChunk () (at Assets/Scripts/WorldGeneration/Chunk.cs:92)
Chunk.Update () (at Assets/Scripts/WorldGeneration/Chunk.cs:52)

I tried to figure out how to fix, but didn’t find anything :\

Alex,

How many parts are you willing to do about this tutorial so far?

Thanks for sharing your knowledge, I’ll take a look on it.

Hey everyone, I just got some time this weekend to work a little on part 8. I made some performance changes, added some trees and added caves. http://alexstv.com/index.php/posts/unity-voxel-block-tutorial-pt-8

With the release of Unity5 screen space ambient occlusion is available for free so I decided not to make this part about ambient occlusion even though it looks cool.

I’ve been looking into how to do biomes and I’m not sure yet what the best way is but I’m thinking it would be possible to adjust the variables for terrain generation based on location creating some variation in things like mountain height, tree density and cave size over large distances. As for the ambient occlusion, sorry if you were looking forward to that but try Unity’s screen space AO, it’s pretty good.

I’m not sure how to do that really, I’m not all that great with shaders but someone that is might be able to do something like that.

I’m not working on the tutorials routinely because I’m busy with my job and side projects but I really enjoy working on this tutorial when I can so I’ll just keep going as I think of things to add. I hope as far as the project has gotten people using this tutorial to research how to make a voxel game could continue on their own if they feel like it since it’s taking me so long. At some point I might consider moving from the tutorial model to creating an open github repository where I can just add new stuff continually and anyone who wants can just use it.

1 Like

Finding this tutorial very useful! Of course, I’m having to greatly edit the code to suit the type of game I’m making, because there’s already enough Minecraft clones lol

One concern, however: what do I do for collision? Making a test FPSController leads me to fall right through the terrain.

Could add a mesh collider;

MeshCollider mc = chunkObject.GetComponent<MeshCollider>();

Mesh mesh = new Mesh();
mesh.vertices = chunk.Verts.ToArray();
mesh.triangles = chunk.Tris.ToArray();
mc.sharedMesh = mesh;

Can also pre optimise the mesh data with a greedy mesh algorithm.

You can also use box colliders around where the player is if you want much better performance, and shift them to fit the player’s movement. Two downsides: you have to write your own voxel raycaster if you don’t want to have to extend box colliders all the way out to the reaching distance for modifying the terrain, assuming that your players should be able to modify the terrain in this way.

And also, it won’t work well for non-cubic voxels. You would have to get around that by using multiple colliders for those types of blocks (assuming you don’t want slopes. Those make things trickier!)

Generally, much easier to go with a mesh collider. It’s just awfully expensive.

1 Like

Would be nice to see actual attempt to get rid of polygons completely and render voxel geometry directly, because when people talk about voxels and the first thing they say is “and that’s how we will convert that to polygons”, it is depressing. The point of voxels is to get rid of limitations imposed by polygonal systems.

There should be plenty of papers on the subject, many of them have been around for years.

Would that apply if you want blocky voxels as well? I’m actually not sure what this means but you’ve made me curious about it. What does it mean to ‘render voxel data directly’? Voxels could just be data, like the block type, and whether it’s solid or not… not sure how to render that directly.

Yep, it would apply if you wanted blocky voxels, because that would be faster to compute render/optimize.

It means that you do not ever create a mesh. You draw ONE fullscreen quad with a shader or use compute shader and it renders terrain/whatever using provided voxel data in a buffer (by highly optimizing raycasting, for example). No polygons, no triangles, no mesh management. Pretty much all modern hardware should be able to handle that easily. You could probably even plug unity effects like ssao in it, as long as you do it right.

Yet every game insists on triangulating potentially infinite number of cubes. Which is why I said it is depressing.

The beauty about voxel data is that you have fixed memory requirements, so no matter what happens, you’ll always draw the scene. The problem with triangulation is that the scene has potentially infinite memory requirement (If I take 64x64x64 voxel block and kick out voxels in very specific patterns, it will result in 780k triangles).

Here is 6 years old demo.

https://www.youtube.com/watch?v=TjmRPjnWJ5g

And here’s recent one:

https://www.youtube.com/watch?v=ij0vw8yTCsY

That’s voxels.

2 Likes