Sunday, April 9, 2017

Various Miscellany (Part 1)

This blog post covers a few miscellaneous and unrelated issues I've been fixing up.

Some time ago I added the capability to color mountains with gradients.  When used with white as the top gradient, it creates snow-capped mountains:
What may not be obvious there is that every mountain has the same amount of "snow" regardless of height.  At the time I implemented that, every mountain was essentially the same height, so this was mostly irrelevant.  But when I changed my mountain symbol approach, there were mountains of many different heights, but they all got the same amount of snow:
You can see here that even the tiniest hills have "snow".  What I really want is for the snow to start at a certain height consistently across the mountains.  Because I draw mountains at one scale and size them to the map in a separate step and other factors, that turned out to be a bit more challenging than I expected.  Eventually figured out the right incantations:

You can see now that only a couple of the tallest mountains have white summits.  I also switched over to a radial gradient so that the snow line curves around the mountains, but to be honest the effect is pretty subtle.
When generating rivers, I push down the terrain where the river runs.  This puts each river in a small valley, and when I generate a map using psuedo-3D shading, the rivers get nice shadows, as you can see on the river system near the bottom of this map.
 It occurred to me that I could get a similar effect even when I'm not generating 3D shading by using the same technique I use to put dark shading on the coast.  I could draw a dark line under the river and then blur it to create a shadow along the river:
This actually works pretty well, but a fairly easy improvement is to offset the shadow in the direction of the sun, and offset an "anti-shadow" away from the sun, so that the rivers get a bright and dark side, as with the real shading:
This works very well when the map has forest masses, since the shadows from the forest mass reinforce the shadows on the river banks and vice versa.

By the way, the sun direction is pretty much hard-coded into the program.  When I eventually get around to enabling the light direction to come from either direction I'm going to have some work to do.
Dragons Abound has a mode for producing a "geopolitical" map where each country or political region is given a different map color:
That's kind of a cool look -- it reminds me of the maps from my school books.  I also wanted a version that identified countries in a more subtle way.  The way this map from Maxime Plasse over at the Cartographer's Guild handled political divisions struck my eye:

The soft colors along the borders help distinguish the political units without obscuring the other map features.  To add this to Dragons Abound I draw a line of the appropriate color along the border and then apply a significant amount of blur.  Unlike Maxime's map, I don't draw the color along the coast, and I put it under features like mountains.  To keep it from blurring into the adjacent country, it is clipped to the country it represents.
I like the subtle color overlay this creates and thought it might look good if it covered the entire country but still let the terrain underneath show through.  To do this, I filled the country with the regular terrain and then used SVG to overlay a transparent version of the country's geopolitical color.
Generally this looks good, but you can see there's a problem with the mountains.  The mountains are added after the rest of the land is filled, and their color is set to be the color of the underlying terrain.  So the mountains don't have the overlay color mixed in -- they're just the color of the underlying land.  One solution would be to draw the mountains before adding the overlay color, but this would have the bad effect of adding the overlay color to the "snow" at the top of the mountain.

A better solution is to mix the overlay color into the terrain itself (rather than use an SVG overlay), so that when the mountains pick up the terrain color it already has the overlay included.  But how do you take a background color and an overlay color and mix them together to get the resulting combined color?  It turns out this general problem is called alpha compositing.  The specific case of overlaying a transparent color on a background has a fairly simple implementation.  So I implemented this and (after figuring out the hard way that SVG expects only integer RGB values) this is the result:
As you can see, the mountains now pick up the (composited) land color correctly and the snow is white.


  1. Those river shadows just made this whole thing pop for me. All of a sudden I saw the bend of a river surrounded by forest and thought "Woah, I want to go explore that".

    Can't wait to see the next addition.

    1. Thanks, I also thought it added a lot. And it's consistent with the forest shadows, which makes them more natural looking (I think).

  2. I'm sure this has been asked a million times, but is your code available anywhere to play with?

    1. Not yet -- I may release it at some point. If you look to first post on the blog, there's a pointer to the code I started from, which you might find interesting.