Thursday, December 8, 2016

How To Decorate a Mountain

My previous post ended with Dragons Abound producing mountains like this one:
There are still a few problems I want to clean up and a few details I'd like to add to improve the quality of these mountains.

The first problem is that the program still occasionally scribbles outside the lines:
That's undoubtedly due to a mistake in the logic of stopping and starting scribbles across the concavities, but I don't feel like trying to untangle that problem any further.  Instead, I'm going to apply an SVG clipping path to the scribble area.  This will clip off any scribbles that go outside the scribble area.

You might wonder why I didn't just use a clipping path in the first place and scribble back and forth across a big bounding box and let the clipping path fill in the scribble area.  The problem with that approach is that you lose the nice "turnarounds" at the ends of the strokes, and that's really what makes a scribble look like a scribble.  You end up with something that just looks like hatching:
This image illustrates the next problem:
The red line here is the "ridge line" that comes down from the top of the mountain and forms the edge of the shaded area.  Because it is seen end on in perspective, the back-and-forth line of the ridge is exaggerated.  But you can see the problem:  The perturbation up at the top is enough to send the ridge line outside the silhouette of the mountain.

I can solve this problem by scaling the perturbation by the width of mountain.  Up at the top where the mountain is narrow there will be less perturbation, and down at the bottom where the mountain is wide there will be more.  Measuring the width of the mountain at every point down the line is tedious, but it turns out that it is sufficient to scale the perturbation as if the mountain were a perfect equilateral triangle.

It's hard to show an example of a problem that isn't there, but here's a few mountains generated with these fixes in place:
Now let me move on to some additional features.  When I compare the above mountains with these examples:
I notice that the hand-drawn examples have additional details on the lit side of the mountain.  Basically just lightweight, random scribbles running up the face of the mountain.  I'd like to add something like that to my mountains.  A starting point might be a line like this:
I call this a "minor ridge line" because it represents a ridge running down the mountain, not end-on to the viewer like the ridge line that separates the lit and shaded sides, and not in total silhouette like the two sides of the mountains, but rather at an angle in between.  Adding some shading can improve this illusion:
(Ironically, my "hand-drawn" examples look more mechanical than the computer-generated examples!)

To start with, let's see if I can get a line down the lit face of the mountain.  To start with, I'll make a line from the peak of the mountain down to the middle of the lit face, and pick a spot about halfway down:
That will be the starting point for my minor ridge line.  Then I'll pick a spot on the baseline of the mountain to create a line at about the same slope as the right side of the mountain:

Let's see if I can generate that.
Okay.  It looks a little odd if this ridge line is straight while the mountain side is concave, so I'll add some code to make the ridge line approximately as concave as the mountain side.
Now I need to add some perturbation.  Since this ridge line is roughly at 45 degrees to the viewer, I'd expect to do some perturbation in the Y axis (as with the mountain sides) and some in the X axis (as with the main ridge line).  However, it turns out that adding perturbations in the Y axis looks weird:
So I only add perturbation in the X axis:
Now I'll set the color to black, use the "hand-drawn" line, and make the line grow from narrow to wide:
This might need some additional tweaking -- that center line is pretty angular -- but there are lots of knobs to play with.

In the meantime, I want to try adding some shading above the minor ridge line.  The line itself is a high spot on the mountain, so this shading represents the low spot or hollow behind the ridge.  Like the minor ridge line itself, I want the shaded area to be narrow at the top of the ridge and wide at the bottom.  I can reuse the ridge line as one side of the shaded area, and then add another line that starts from the same point but gets wider near the bottom.  If I apply the same perturbation to both lines, I get something like this:
Then I just need to scribble in that area with some shading.  Because this area is relatively small and I don't want it too dark, I use lightweight lines.
This minor ridge line won't appear on all mountains; it will be an option to add flavor.

Another detail I want to add doesn't appear in my examples of hand-drawn mountains, but is something I think can look good.  The idea is to add some additional lines along the right side of the mountain to suggest structure.  Where there's a sharp angle in the right side line, I'll extend the mountain line along one of the existing lines, as with these Photoshopped examples:
To start off implementing this, I write a routine to scan down the right side of the mountain looking for angles between 0 and about 90 degrees.  I start the scan part-way down the mountain, because putting a horizontal structure line up near the peak is likely to run into the shading area.  Here's an example of a mountain with the potential structure points identified:
Now I have to (randomly) select one of the two line segments and extend it.  I'll also taper the line so that it trails off.  Here are some examples of what this looks like in action:

I'm pleased with how this turned out -- it's a subtle effect, but it really adds to the "hand-drawn" quality.  I can do the same thing on the ridge line that defines the shaded area.
Implementing these last two details forced me to write some code to try to keep the decorations on the mountain from overlapping.  One thing the human eye does effortlessly is find open space, and not draw one thing on top of the other.  That's much harder for the computer.

This is getting long, so I'll save some more of the detail work for next time.  On a final notes, sometimes the mistakes can be striking:

No comments:

Post a Comment