Log in to follow projects

Following a project allows you to receive updates via email. It also lets the owner know that you like them.


Generating 3D Islands in Unity

By Oliver Smith

Just playing around.

100% complete
4 followers 14380 views
About Log (2) Discussion (2)

Part 2. More island adventures

Perlin noise is a way of generating random values based on input. If you change the input a little bit, you get random output that isn't too far off from the previous output. If you change the input a lot, the output may change a lot. If you use 2D x,y coordinates as input and use the output as the z coordinate, you'll get something that looks kind of like rolling hills without having to do anything else. And of course, hills can be turned into islands by adding a water plane somewhere. It's a pretty cool trick, actually. Unity has a built-in Mathf.PerlinNoise() function, although I didn't use that here.

These islands were shaped using Perlin noise, with coordinates farther from the center given an extra pull downwards so they're surrounded by ocean.

Mountains were shaped by using another Perlin noise function (scaled up to be more dramatic) on anything above a certain height in the original Perlin function, so z values that were already high get higher. It's not very sophisticated but it's quick and easy.

Next, I added some vertex colors to try and copy Jack's original image (see Part 1). Trees (modeled by Jack) were also placed using Perlin noise - that's why they tend to clump together rather than being completely random.

Moving the camera in close, adding some Unity fog and a sun from scrawkblog.com (scrawkblog has a ton of completely awesome projects), it looks like this:

Sorry for the glowing ghost water I had in there for a while. Next up, figuring out how to add textures to different parts of the terrain:

And this was how it was looking before we decided to scale back the scope of the game this was going to be for:

In that screenshot I'm blending the vertex colors together rather than keeping them at fixed boundaries. The "mountain" regions are also flattened into plateaus to make them more walkable. There's a ton of rim lighting on the ground as well. There wasn't a lot of intentionality in this, just a lot of playing around, so it ended up looking kind of alien I think. There's also a blocky large-pixel texture on everything. I was sort of trying for a large-pixel look like Let's Go Camping, but they did it way better.

Finally, here's a bonus .gif of a day/night cycle (the sun comes up after 30 seconds, and sorry again for the weird ghost water):

Thanks for reading! If you're curious to see where this was going, check out our game in progress (even though it doesn't actually look like this anymore).

Part 1. Voronoi diagrams

First, my friend Jack made this concept image in Blender:

We wanted a procedurally generated, flat-shaded style for the game, so I thought I'd try and make a terrain generator in Unity. I got started by reading this awesome article from Amit Patel. Amit's flash demo has a 3D mode that seemed like a good thing to try and emulate.

I'm not going to go into detail since Amit's article already does that, but basically he starts with a 2D Voronoi diagram, assigns terrain types to different polygons in the diagram, and then converts to 3D by assigning a height to each section that is not part of the ocean.

I couldn't find a Voronoi diagram generator for Unity that was not part of a shader, so I decided to write my own implementation of Fortune's algorithm (an algorithm for generating Voronoi diagrams). That ended up being a lot harder than I thought1, but after a week or so of debugging the kinds of weird errors that only happen once every few thousand polygons, I got it working. It's really easy to add buttons and debug info in Unity's editor, so that helped a ton trying to visualize things. Here's what stepping through my implementation in debug mode looks like:

My code ended up being kind of hacky, but it was also pretty slow - slow enough that it was going to be annoying to test a bunch of islands with thousands of polygons. The Unity editor also seems to crash a lot when reloading code that uses circular references. I spent some time optimizing, but even after some big speed improvements it was obviously going to be a huge time sink. About then I figured out that Unity's Pro version lets you use plugins written in C++, so I decided to try to get the Voronoi code in the Boost library working instead. It took me a long time to remember how C++ works, and then a bunch more time to convert the output of that library into a similar graph structure to Amit's code, but eventually I got that running too and it did turn out to be a better approach.

With my new fast and efficient Voronoi generator, I got to see some early results pretty quickly:

More islands in the next post!

  1. Actually, using a Voronoi diagram was a mistake in the first place. I could have seen results much faster with a simple hex grid.