Entry 29 - Fun With Unity Terrain & Caustics - August 6, 2015

Having fun with Unity terrain
I had a lot of fun with Unity terrain the last days. Here are my highlights.

Grass
I want to use a lot of grass in the game so I enabled it and made it really dense. The problem: Unity's terrain grass is incredibly slow. It's okay for very tiny terrains but it's slow as hell for larger terrain when you work with a good looking grass density. Unity actually only shows grass which is close to the camera but this doesn't seem to improve the performance much. The mere existence of a lot of grass that is not even visible makes the game run very slow.

Even worse: When having much grass on the terrain it will also affect the performance for adding and removing terrain trees add runtime in a very negative way. Unfortunately this is what I have to do a lot in Stranded III.

So I discarded the idea of having one terrain per island and decided to split everything up into fixed size terrain chunks. That's how most open world games do it anyway. This is awesome because terrains can be even larger with this technique (it allows a nearly unlimited size in theory) but of course it makes the underlying logic a bit more complicated. It solves the problem with the dynamic tree adding/removing-performance because Unity has to update only small chunks every time. I'm currenlty using chunks with a terrain resolution of 128x128.

Anyway: My current conclusion for Unity's grass is that I simply can't use it because it's too slow. I know that there are faster solutions though and I'll try to find the one which works best for me.

Terrain Heights
A very important thing to know when working with Unity's terrains in code is that the heights are not saved in the common [x,y] order but in [y,x] order. This is very confusing and makes it super annoying to use (at least in my opinion) but whatever.

Here's a little image visualizing the problem:

So don't forget to swap X and Y (or Z) at the right places or you'll run into fun problems.

Terrain Neighbors
Another thing which took me some tries to get right were terrain neighbors. When using multiple terrains right next to each other you have to mark them as neighbors, otherwise their edges will be very visible. This is a mutual process. So you have to tell terrain A that it has neighbor B on the left and you also have to tell terrain B that it has neighbor A on the right.

For some reason I'm accustomed to a coordinate system where the Y-axis is pointing downwards. Meaning: Increasing Y makes things go lower. In Unity it's the other way round. The Y-axis is pointing upwards. Increasing Y means that things go upwards. The Unity developers were consequent about this when it comes to terrain neighbors only that the Y-axis is replaced by the Z-axis in that case because terrains are positioned along the X- and Z-axis.

It's not defined what left, up, right and bottom is so I mixed top and bottom up in my first attempts - but I managed to fix it. Here's an image about the correct neighbors. Maybe it's useful to some people:

Caustics
I also did caustics for diving. I'm using a projector for this with a custom tiled projector shader which allows me to cover bigger areas by tiling the animated caustics texture.

I'm still having some problems with the caustics though: They don't tile seamlessly. There's a visible edge which is NOT caused by the texture. See image below. They are not affected by fog. On some models they cause strange artifacts.

I guess that at least the first two problems can be fixed with some shader magic but I'm not very experienced in that topic so I'll probably have to invest some time to get these things right.

(don't try to click it for a larger version, I scaled it down because it's ugly )