## Thursday, August 10, 2017

### Decorating the Ocean (Part Three)

In the previous posts, I've described how Dragons Abound draws oceans and how it creates a common coastline embellishment where a series of parallel lines are drawn outward from the coastline:
In this post I'm going to describe how I've implemented another common embellishment.  Here's an example map that illustrates what I'm going to try to do:
In this map, the ocean is indicated by parallel horizontal lines that radiate a short ways from the land before trailing off.  These might have originated as more illustrative wave symbols, but now they're more graphic and stylized.  This example map is nicely hand-drawn and quite artistic.  A fair number of fantasy maps use this technique, but few of them do this nice job with it.

The straightforward approach to implementing this embellishment would be to walk along the coast and draw lines outward and some interval.  But there are a couple of problems with this approach.  First, you can see that the lines are at regular vertical intervals.  If you just step along the coast a certain distance, the lines will be closer together where the slope of the coast is shallow (i.e., close to flat).  Another problem occurs when the coast bends so that the lines from two parts of the shore meet, as happens on the example map near Dennies Point to the upper right.  You would need to make sure as you walk along the coast drawing lines that the lines you draw on the left side of this feature meet up with the lines you draw on the right side of this feature.  A final problem is that you sometimes have to draw lines that don't start from the shore at all, as happens on this map at each of the Points.

It's probably better to think of this embellishment as a pattern that is filling a buffer zone around the coastline.  After some thought, my approach to implementing this was to fill the entire ocean with parallel horizontal lines, and then mask away the parts that were away from the shore.  Let's see how that can be done.

To start with, I need to fill the ocean with the basic line pattern.  This is simply a matter of drawing a series of horizontal lines into the ocean layer of the map, like so:
All I've done here is fill the ocean with color and then draw lines on top.

The next step is to mask away the lines that aren't near the coasts.  However, as I mentioned in the previous post, the problem of "draw a line X pixels away from this polygon" is actually very difficult.  So I can't just expand the coastline and use that to cut off the lines.  Instead, I'll make use of the same trick I used in the last post -- drawing the coastline with a big pen.

To see how this will work, let's first visualize the desired mask.  Typically, a mask is just a black and white image that blocks drawing where it is black.  To start with, I can create a mask that is entirely black and use that to mask the ocean stripes.  This is the unsurprising result:
The mask blocks out all of the lines.  Now I want to modify the mask so that it shows the lines near the coast.  To do this, I want to paint the mask white in a swath around the coast.  How do I do that?  Remember how I used big pens on the coast to create the previous embellishment?
I'll do the same trick, only (1) I'll only draw one big white coastline, and (2) I'll draw into the mask instead of into the display.  The mask will then allow the stripes to show through wherever the big white pen drew:
And indeed, the stripes are now showing along the coastline.

This is too obviously mechanical, so let's working on making it more artistic.  To start with, I can vary the width of the mask so that the distance from the coast isn't always the same.
This effect is subtle, but you can see how the ocean stripes have shrunk in some areas and grown in others.

If you examine the example map above, you'll see that the stripes in that map don't all abruptly end but trail off or get spotty near the end.  Having the stripes trail off (get narrower) is not possible the way I'm doing this, but I can make the ends spotty and irregular.  What I'll do is apply a noise filter to the map to perturb the edges of the map.  A little blur helps too.
That's not quite the same as the hand-drawn version, but it does a lot to break up the artificial edge.

Another problem is that the lines are too regular.  We can start to address that by adding a slight variance to the spacing.
Now I'll add some variation of the line width as well.
Finally, I can add some jitter to the lines so that they aren't so straight.
And putting it all together:
I think the final results look pretty good.