Lining the Terrain

Introduction

For various reasons, I need to draw some lines on terrain in Unity. I’m not sure if these are the algorithms I’ll end up using, but given that I couldn’t find anything but pseudo-code for them (okay, I didn’t look that long), here they are in C# using Unity terrain splat maps.

Splat maps

There are a couple (literally, two) good old-ish articles on Splatmaps – try this one if you’re new to them. To actually apply colour to the splat map, in my (very) specific case, I use the following function. You’ll want to take this function, change it to apply to your texture indices, make it waaay better then send it to me. You know. Just because.

In my case, I wanted the texture in slot 3 (index 2) to be applied wherever I splat’d. I also clamped the boundaries, just to avoid any awkward crashes that left the terrain undressed.

To use the later anti-aliasing methods, this function takes a float, c, indicating the transparency. This is calculated very simply (too simply?) as a linear combination of old textures and new textures. When c is 1.0, we only splat, when c is 0 we do not splat at all (or at least we have no effect).

In addition, all x and y are in terrain alpha map coordinates already – see the other articles if you don’t know how to get into those coordinates.

That’s all we need to get into the algorithms.

Bresenham’s Algorithm

Bresenham’s algorithm is an extremely efficient line drawing algorithm, with two drawbacks –

  1. It does not handle anti-aliasing (which has a wide range of implications).
  2. It can’t turn left. Gah, it can’t draw vertical lines. Not even lines that are very close to vertical.

Zoolander, "I can't turn left".

If you can live with these restrictions, this algorithm will do well for you. This one is adapted from the basic algorithm found at its Wikipedia page, except that I splat on either side of the line as well in order to make it more visible.

This produces something like

Bresenham Example

Although this looks fairly good (thanks Unity!), we get nothing if the line runs in the other direction.

Xiaolin Wu’s Algorithm

Mortal Kombat - Bresenham vs Xiaolin Wu

This algorithm is considerably more complicated (and not as fast), but given that it handles both anti-aliasing and vertical lines, I think we can forgive it that. This version is also based on the Wikipedia article.

This algorithm also uses a range of helper functions, which are listed first. As per the Wiki article, plot is replaced by splat which was given above.

Helper functions

The main algorithm is

 

This produces something that looks a lot like:

Xiaolin Wu Example

Although this looks quite faded, this looks more effective at a lower zoom and could (hopefully will be) improved as discussed below.

Improvements

In my case, I’m drawing a line with a width and a height – to be precise, a rectangle. My code is drawing from one corner to the opposite corner, so actually drawing out the rectangles would no doubt produce a better result. Hopefully to come.

End!

Any questions / improvements / spam, feel free to get hold of me in the comments. Except the spam. I’m always watching.

Tagged with: , , , , , , ,
Posted in Unity

Leave a Reply