Monday, March 27, 2017

Sprucing Up the Forest

  The basic forest mass is working, so now I'm going to spruce it up a bit.  Get it?  Ha, ha, snort. 

Um, anyway.

Here's how it looks right now:
To start with, I'm going to turn off the biome backgrounds and put in a solid color for the forests, and use a different color scheme:
One problem with filling in the forests with a color is that it covers over any "holes" in the forest.  My algorithm for finding the edges of the forest finds these gaps, but SVG fills polygons assuming that they are solid, so it covers over any isolated open spots within the forest mass.  That's something I might consider fixing at some point, but for the moment I'm just going to accept that shortcoming.

In the map above, I expanded the view a little bit because I wanted to point out the large city on the right side of the map.  One thing I want to add is to remove forests near the cities, to reflect the impact man has on his environment.  Initially, I can just carve a circle of forest away around every city, with larger cities using more forest than smaller ones.
If you compare the two images, you can see on the right side how the forest has been carved back from the city.  But notice there's no change by the small mining village in the middle of the map -- it's not big enough to have much impact.

One problem with this approach is that it can look pretty artificial with a smooth and regular circle cut out of the forest.  A lot of times removing the forest has ripple effects so this isn't so obvious, but since I can't count on that I'd like to make my circle less regular.  I'll borrow a trick that I used when making islands, and I'll perturb the removed area with noise to make it less regular.  After some tuning of the noise parameters, I have this:
You can see how noise has changed the removed areas to make them less regular.

Another thing I'd like to do is add some mottling to the forest area.  If you look at the maps above, you'll see that the land has a subtle mottling effect.  And in this example map, you can see the same sort of thing in the forest:
The way Dragons Abound mottles the land is to draw each of the underlying locations in a slightly different color and then blur it all together.  This won't quite work for the forest masses, because the edges don't match with the underlying locations.  (The forest edges have been smoothed and then made bumpy, so the edge no longer runs along the edges of the underlying locations.)  A possible solution is to fill the forest with a flat color (as above) and then mottle the interior locations; let's see how that works.

The first challenge is just figuring out the interior locations of the forest.  That turns out to be harder than I expected.  I create the forest edge by walking where forest meets non-forest, and that doesn't give me enough information to know whether an arbitrary location is "inside" one of the forest edges or not.  The straightforward solution is to take a location and check to see if it is within the SVG path that makes up the forest's edge, but telling if an point is inside an arbitrary polygon is non-trivial, and having the polygon represented as an SVG path is another big complication.  The SVG path isn't a simple list of points, but actually a bunch of Bezier curves.  It would seem to be almost impossible to figure out whether an arbitrary point is on the inside of a polygon made of Bezier curves.

But amazingly enough, someone has already solved this problem!  All I have to do is clone this code, clean it up a bit and it should work just fine.
Here's the forest all divided up and mottled.  I forgot to turn off the edges, so it's also an interesting look at the locations underlying the map.  (The blank area in the lower right is one of those holes of non-forest inside a forest.)

Unfortunately, this is really slow.  It occurs to me that at one point during the creation of the forest edge I actually do have the edge as a list of points, so I could use that and avoid the work of interpreting the SVG path.  Now I just have to tell if the point is inside a polygon with straight edges.  The code for that problem is a lot simpler.  Amazingly, this code works first try, and is much faster:
You can see that the locations around the edge of the forest often overlap the edge.  The solution is to clip them to the forest outline.
The clipping creates spots along the edges where there's no background color, so I need to add that back in, and throw a blur filter on the mass while I'm at it.
The mottled forest looks much better than a flat color, I think.

One trick I can apply at this point is to darken around the edges of the forest to give a bit of a 3D effect.  The easy way to do this is to draw around the edge of the forest with a fat line a little darker than the fill color, clipping to the forest.  Only the part of the line inside the forest is visible, and I can include that in the blur so that it gets blended into the rest of the forest fill.
I like this effect; I may have to try something similar for the coast of the land.

(BTW, a shout out to /u/bbqsamich.  If you compare this map to the one above, this is where I implemented your suggestion to vary the density of mountains based on height.  I think both versions look fine, although I think I prefer the original placement.) 

Another way to create depth is to add a small shadow to the forest mass.  This shading should be consistent with the shading on the mountain symbols, so it will fall the west side of the mountains.  To implement a shadow of this sort, I draw the forest mass in partially-transparent black and offset it a bit.  The shadow is drawn first so that that forest mass covers all but the edge of the shadow.
This might look better with a little bit of blur; I should also consider basing the color of the shadow on the land, rather than just a neutral color.  (Renoir would have suggested a violet shadow; the Impressionists understood that a shadow has the complementary color of the light source, but that's perhaps a bit too detailed for a fantasy map :-)
This effect looks pretty good, but it may clash with the way the mountains are illustrated (they don't have any cast shadows at all).  I'll have to think about that.  There's also a problem with the way the rivers and borders go "under" the forest, but this is a good stopping point, so I'll address those concerns next time.


  1. Your mottling seems a lot more uniform than the reference, which has more mottling around the edges and relatively scarce spots in other places.

  2. I hadn't noticed that, but you're right. Something to keep in mind as a possible improvement (although I'm not really trying to slavishly copy any particular map).

  3. Awesome as always. The forest still feels a bit flat tho, it would really help if there was some more detail in the forst itself. Like in the reference map you showed. Will you be trying an effect like that as well?
    The mottled effect also kinda looks more like a gradient to be quite honest. In the reference image it's more just dots made with the brush. Maybe you can restrict your code to use darker spots less frequently then the lighter colors?

    Can't wait to see the next update :-)

  4. Thanks!

    Interior texture is in the next update ... be patient! :-)

    I've gotten a lot of feedback on the mottling, so I'll probably try out some variants at some point. Thanks for the suggestion.

  5. This comment has been removed by a blog administrator.