Island

First things first, and credit where credit is due; I’ve stumbled across ProjectSalt on Steam and been playing it for a couple of days. Being a fan of exploration games and carribean style-ish pirate games it seemed like a game worth trying. After a few days my inspiration levels had risen quite high and I decided that I wanted to make something similar and try my hands at proceedural generation as I had surprisingly little experience with it after all these years.

So, what’s the core of ProjectSalt? Islands. How do we make an island? ‘Tesselating a vertex field!’ … was my original thought, but in the end I reeled myself in and took the easier approach and created a terrain heightmap. My approach was to make use of a couple of Unity’s Mathf.Perlin calls, which is practically infinite in randomness, and mix them together. After tweaking a couple of numbers and settling for an island to follow throughout the tutorial, I ended up with this heightmap:

Now that I had that, I could proceed to creating my terrain. Treating each pixel as one vertex I could now just make a vertex field with the same number of vertices arranged in width(x) and depth(z) as the texture had corresponding pixels of width(x/u) and height(y/v). With the heightmap at the ready I just sampled the height from the map at each vertex and ended up this:

 

Nice looking terrain, huh? I thought so too until I quickly figured that ‘This doesn’t look very much like an island, let’s fix that!’ and so I had to smooth the edges somehow. I did this by using a circular, smooth-edged texture mask when creating the heightmap, so I could sample it at roughly the same uv as setting pixels in the heightmap and mix it with the final perlin noise. It turned out pretty well!

It’s shaping up, now it actually looks like it could pass for an island, doesn’t it? But it’s still missing some stuff, like a shader to add some sand, beach and cliffs. For shading a terrain, you usually make do with splat shading, which is most commonly that the vertices in the terrain will also have colors, as opposed to the normal positions, normals and uvs. These colors map in the shader to a specific texture and such you can paint a terrain with colors and get your textures “splatted” onto the terrain. The way I set mine up was that red color was for beach, green color was for grass and blue color was for cliffs. So I had to decide some things, how high should the beaches be and at which steepness did cliffs appear at. After doing that and making the shader, I ended up with a much nicer looking island than just a dull grey one.

 

This, this is an island. After admiring my new proceedurally created island, I felt like I was missing something. What kind of island doesn’t have any water surrounding it!? No island at all I say. So I ventured to make some water and at first I thought ‘Let’s make a huge vertex field in code and make it all wavey!’ … Then it obviously hit me that it would cost a buttload of processing power, time and energy to make something like that efficient and fast enough so I decided to go the easier route and let my GPU do the work for me at minimal cost instead.

I put a bunch of planes with a decent vertex density around the world and made them a shader with a basic water texture and a one color waves texture. Now I could sample the waves texture in the vertex shader and extrude the vertices up(y) to make some static waves. (FYI: This approach might not work or be the optimal approach for some older phones.) I made sure to use the vertices world xz coordinates instead of the normal uv texture coordinates to sample the waves texture so that wherever I moved the water in the world, the waves would show as they would be at that position in the world. That makes it easy to move the planes of water along with the player and he/she would be none the wiser that we’re doing it. All I had to do now was to scroll the waves texture along some axis at some speed and I would have some dynamic waves. It looks pretty good with minimal effort, time and processing power all in all.

So in the end we ended up with our island, surrounded by moving waves. How nice!