Figure 1: Pixel Dust appears to be reading up on G'MIC lore in the wee morning hours. What might emerge from such midnight lucubrations, one does wonder.

The Hair lock Filter

The Hair lock filter grows out of the ““Do Your Own Diffusion Tensor Fields”  series, in particular “Tensors for the Tonsorially Challenged.” The command line walk through in that tutorial discusses how the filter diffuses noise into a simulation of hair strands. Visit those pages for the theory behind this filter, which will not be discussed much here.

This filter renders hair locks as they might appear at about ½ to 2 meters from the viewer, roughly, head-and-shoulders portraiture scale. The filter supposes that the digital artist will compose a complete head of hair from a number of hair locks, and that each lock, in turn, consists of two or three plies of hair.

By default, the filter renders hair semi-transparently and, in practice, has been designed around the idea that the skeletal image, which provides a model for the hair lock, has been drawn at about 1 ⅓ to 2 ½ times over sized, anticipating that hair locks may be sheared, rotated or reduced before final placement in the image (See Figure 2). Out of the box, the hair rendered by this filter is too fat, by design.

Before using the filter, an artist should have a fairly advanced sketch of their work, or a fairly well worked out game plan (much the same thing). Two things which need to be settled before using the filter successfully are the geometry of the hair locks, that is, how many and how do they drape off the head, and how the hair is lit.

The artist expresses the geometry of the hair locks by drawing a skeleton of a few representative hair strands (See Figure 2). These can be Bézier curves, a series of straight lines warped into shape, high contrast images of existing hair or free hand curves. The example in Figure 2. was first prepared in Inkscape. The artist used the Interpolate Sub-Paths effect in the Path Effects editor, developing the body of the skeleton with a seven-step interpolation of two initial curves. A few extra “dangling strands” in the lower right portion of the skeleton completed the art.

The artist passed the exported bitmap through G'MIC's -smooth command with a very high anisotropy setting. This last step affects how hair strands distribute themselves at the ends of the hair lock, which, without the smoothing step, can space themselves in a manner too uniform to seem natural. We go into this matter with greater detail in the walk through.

The artist expresses the direction of incoming light, hair coloring, and a number geometric properties in the Hair lock filter dialog box, which we describe in the next section.

Hair Lock Dialog Box

The Hair lock filter needs three chunks of information, each having some particulars. In most cases, one expresses these with relative amounts that vary from zero ('not at all') to one ('a lot'), with the default calibrated so that the most typical input corresponds to ½, 0.5 ('just right, usually'). Some particulars represent angles – light direction and hue – and these vary from 0 to 360°. The base hair color is set by the standard color chooser dialog box common to all G'MIC-Gimp filters; the scalar controls run from 0 - 255 instead of 0 - 1.

Figure 2: A Skeleton image

Geometry

You tell the filter about the Geometry of your hair lock by providing a skeleton image depicting a few representative strands. This image should be your active layer when you choose the filter from the Gimp-G'MIC filter menus. Apart from that, the filter needs some guidance about the hair itself, how much hair may spread from skeletal lines, how dense is hair growth, and the average length of a hair strand.

  1. Spread = float(0.5,0,1). The filter learns how to position hair strands from the orientation of skeletal lines. This control tells the plug-in how far it may position strands from the centerline of these skeletal lines. Close to zero, and hair strands will orient along skeletal lines and stay out of the regions between them. This extreme is useful for distributing hair unevenly. Think of the vanity locks that balding men (in denial) comb across their bare pates. Close to one, and the hair radiates out from skeletal lines and forms a uniform hair lock.
  2. Thickness = float(0.5,0,1). This control sets the density of distribution. Close to zero, the filter will draw only a few strands, a quite straggly effect. Close to one, the filter draws a lot of hair, giving rise to the “helmet hair” effect – the hair mass seems to look like a hat sitting on the head. The middle setting of 0.5 is sufficiently sparse to allow lower hair plies to be (somewhat) seen through upper hair plies.
  3. Length = float(0.5,0,1). This control establishes the length of hair strands. Near zero, these are very short, but lengthen for settings near one. Small values do not render short hair! The skeleton sets hair length, so when this setting is near zero, the filter renders hair strands at lengths set by the skeleton, but as series of dashes. This changes the visual texture of the hair, affecting the length of specular highlights and color variations, which tend to be more saturated. Behind the scenes, the filter starts with a series of colored dots. These diffuse along curves to an extent controlled by this setting, which, toward larger values, begin to coalesce. Colors merge, tending toward means that are often less saturated than the original dots.

Color

These settings establish basic hair colorwith an added control for variance.  In any case, you can – and probably will – further adjust the hair color in Gimp.

  1. Color (dialog box) Sets a base hair color around which Variance (below) perturbs base color. Since you will more than likely build up your hair lock from two, three, or four plies, you should set the opacity to about 100 - 200. See the walkthrough, below, for further details.
  2. Variance = float(0.5, 0, 1) Variance perturbs the base color on a strand-by-strand basis. The amount of this perturbation increases until  variance dominates and the base hair color is subsumed. The most useful settings for “normal” hair reside around 0.1 to 0.3; no two strands are identically colored, nor do they vary from one another all that much.

Lighting

Unless somebody turns on the light, setting hair color is for naught. Three controls, Azimuth, Highlight, and Specular, manage a simple kind of infinite-distance light source. The lighting model is the same as the Finger paint plug-in and its technical basis is a part of the Finger painting walk though. We won't repeat those details here.

  1. Azimuth = float(45,0,360) Set the direction from which the infinite-distance light streams. Ranges from zero to 360° and defaults to 45.° The default value lights up hair strands running transverse to the northwest; zero degrees lights from the left, 180° lights from the right.
  2. Highlight = float(0.5,0,1). Ranges from zero to one and defaults to 0.5. Larger numbers engender brighter highlights but less saturated and darker mid-tones.
  3. Specular = float(0.5,0,1) Ranges from zero to one and defaults to 0.5. Unlike highlights, which project brighter, more saturated hair color, the specular glints are white.

Hair lock Walk Through

Roughly, the hair lock filter hijacks the the smoothing geometry of one image to modify another.

In the present case, we generate and modify a smoothing geometry of some line strokes to modify salt-and-pepper noise. Under processing by the -smooth command and given the smoothing geometry produced from our skeletal drawing, the impulses composing the salt-and-pepper noise elongate under diffusion into string-like structures, a serviceable emulation of hair. Details may be found at “Tensors for the Tonsorially Challenged.

There are few constraints on the skeletal drawing; it should have high contrast and consist of sharp edges. Conventionally, we use black on white gray scale images but white on black works too, as well as red on cyan.

There are many ways to compose the skeletal drawing. Inkscape's Interpolate Sub-paths feature in its path editor is pretty popular with us because we can quickly compose a series of coordinated curves. We have also drawn straight lines in Gimp and then used the “Distort → IWarp” filter to sweep these into various curves. Freehand works as well, and photographs of real hair, a threshold set to capture hair strands, obtaining a black and white images with sharp edges.

One can become quite creative with particulars and to good effect: the quality of the edges has a direct impact on hair appearance. Smooth lines, such as those depicted in Figure 2, give rise to a laminar flow. However, if we should subject this skeleton to some spread noise, the smooth flow becomes turbulent, the hair now wavy. In the following walk through, we will modify an initial skeleton a few times as we ply hair lock samples together.

There are a couple of constructs in a skeletal drawing which do not work as expected. First, crossing lines will not result in crossed hair strands. The present implementation has no concept of depth and cannot interpret crossed lines as some strands of hair going under, or over, other strands. In contrast, one skeletal strand “wins” and cuts the other in two, producing a wholly different effect.

Second, truly curly hair, the kind that forms ringlets, is not easy to emulate. This is also related to the matter of depth, as a ringlet is a spiraling hair lock with cross-over and depth. With practice, we can come close, but the present hair lock filter shows preferences for straight hair – even wavy hair – but hair with over-crossing curls and ringlets requires a certain finesse.

Because the filter has no concept of depth, we almost always render a series of skeletons to different layers – emulating depth with a series of hair plies. This approach actually has considerable benefit, because we can modify the skeletal drawing and settings from layer to layer so that the arrangement of the hair changes from ply to ply. This gives rise to a heightened sense of realism, because, in actuality, the hair on our own heads varies with depth.

We harness the drawing in Figure 2, which, no doubt you recognize, is a skeleton used in the front piece; it corresponds to the lock of hair that flows from the top of the young woman's head, behind her ear and around the back of her neck. We will not use the settings here that we used there, mainly so that we can illustrate the various ends that one can reach from a common start, though the work flow that we use here is the one used for the front piece.

Preliminaries

  1. Start Gimp and load something which looks like it belongs to the class of the image on the left: high contrast lines. If you're just exploring, start with a single, opaque white layer, draw a few lines with the pencil tool, about 7 to 10 pixels around, and, optionally, swirl your strokes with a large setting “Clock/Counterclockwise effect in Gimp's Distort → IWarp filter (200 or so).
  2. Start the Gimp-G'MIC plug-in. Check the filter inventory (middle pane). You should have a “Rendering → Hair lock” item. If not, work your way through the installation guide. You probably only need to refresh your filters.
  3. We want to use this skeleton for a number of plies, so we set the Gimp-G'MIC plug in to output to a “New Layer”, which preserves the skeleton for later use. The setting to adjust your output is on the left hand side, beneath the preview window, the second spinner from the top in the “Input/Output:” widget group. Adjust it to read “New Layers(s)”
  4. For educational benefit, you could set “Output Messages” to “Very Verbose (console)” or “Very Verbose (logfile)” and compare the (eventual) output to the Hair lock tutorial. Just a hint, mind you.
  5. We suggest you uncheck the preview box. The filter can take a few seconds to render, and you don't want to waste time with uninteresting settings. Turn it on after you've made your initial settings.
  6. Before moving on, ensure that the preview window shows your skeleton very near to a 100% scale (the default, but it may have been readjusted). Under the covers, Hair lock employs anisotropic smoothing, which is very scale-dependent. If your preview image is smaller or larger than your actual artwork, it will not give a very representative preview when you eventually check the box back on again.
  7. Choose “Rendering → Hair lock” and review your options by reading “Hair Lock Dialog Box.” If you can't think of anything better, Try Our Settings.
 

Our Settings

Our settings are for a blondish, light brunette shade:

  1. Spread: 0.7 Thickness: 0.6 Length: 0.7 Hue: 40 Saturation: 127 Lightness: 127 Opacity: 175 Variation: 0.1 Azimuth: 90 Highlight: 0.5 Specular: 0.7
  2. We then hit “O.K.” However, if you'd like to see where you're driving, Try checking the preview box (is it close to 100%? See step 6 in the previous box). Play with settings if you like.
  3. Once you have hit “O. K.” wait about a minute. After such time, the Gimp main window should be similar to the image on the left, a partially transparent hair lock layer over the skeleton layer.
  4. The hair looks ghostlike, of course, because its opacity is 50%, and that is handy: you get a quick read on your rendered hair and the skeleton that structured it.

Ply One Review

After we have contemplated our hair over the skeleton, we grow interested in a few more viewing contexts. One of our favorites is to lay a black layer beneath the transparent layer so that we can study the hair itself.
Once studying the hair, our general conclusion, of course, is that it is too perfectly aligned for any human setting, save, perhaps, Junior Prom in an American high school, circa 1957. There's a solution to that; it is called making other plies. We also check light direction to ensure that it is consistent – or interestingly inconsistent – with whatever else may be in a larger illustration context.

Ply Two

Once we've decided that this is a take, we go on to create s second ply, mainly to add variations to the hair structure. We do that by modifying the skeleton image.

  1. To kick that off make a copy of the skeleton layer (important)! By duplicating the layer we have an easy recovery option, should we discover we don't like our modifications.

  2. We then modify the skeleton copy. A favorite for us stems from the “Distorts ->IWarp tool. We criss-cross the skeleton with a low radius (≈ 10), low strength (≈ 0.1), Clock/Counterclockwise effect. See our modified skeleton on the left.
  3. We do the Hair lock filter again, same settings, but with this modified skeleton.

Ply Two Review

The modifications we performed on the skeleton manifest themselves in a somewhat wavier ply.
We decide we like the modifications so far. We turn on visibility of the first ply and compare how they look together.

Both Plies Together

Because our plies are semi-transparent, the under ply shows through the over ply somewhat, and in this case it has sufficient presence that the wavy under ply breaks up the too-laminar appearance of the over ply, to good effect, or so we judge.
We're not quite ready to call it a day. Usually, stray hair strands fly out from a body of hair; there is not so much of that in evidence here. To address the matter, We set out to make a third ply, sparse in character and with a slightly different hue, to overlay the first two plies. The shift in Hue will furnish accent color, breaking up the hair lock's somewhat monotone blond color.

Ply Three

We return to the original skeleton layer and duplicate it again – always, in our work, keeping an unaltered version of the skeleton image handy in case we need to back out.
We harness the IWarp tool again. We set the Move effect to a radius of 40 or so with a deformation amount of about 0.3, and shift the skeleton about thirty pixels this way and that. This amounts to a modest wave. We also used the Counterclockwise effect and a small radius of 8 and a strength of 0.1 to locally perturb hair strands.
To make a sparse ply of hair, we change some settings. Thickness: 0.25 (from 0.6), Length: 0.20 (from 0.70), Redder color:  Hue 20, (from 40), Saturation 204 (from 175) and Opacity 204  (from 175)

Ply Three Review

The change in Hue from 40° to 20° shifted the hair color to a reddish auburn; it is more saturated as well, in keeping with our aim of having accent color. Less obvious is that the distribution of hair is much sparser than in the previous runs. If we compose this as the top ply, the bottom two will still mainly show through.

All Plies combined

With all three plies in place, we have a hair lock that suggests something of the vagaries of real hair. We don't think additional plies are in order. When ply opacity is around the default value of 127, three plies is about at the practical limit, as the combined opacity of the three layers theoretically exceeds 100% opacity.

When evaluating the results of your efforts, consider rearranging the order of hair plies. Also consider shifting their opacities and color using Gimp's native tools. You may save yourself extra rendering.

You might also consider making a second or third ply by simple layer copying and judicious Distorts →IWarp use. The key word is 'judicious.' IWarp unavoidably softens (blurs) pixels as it smears them around. This filter renders hair somewhat oversize so that you could get away with some of that; it all heals, mostly, when you reduce your image to its presentation size. However, there are limits. Also, when unwarped hair is plied over warped hair, the mix of soft focus / hard focus hair strands starts getting weird. For quality work, prefer oversized scales, though rendering takes longer, and adjusting the skeleton and rendering from that.

Postscript

We close out shop with interesting directions and some out-of-the-box notions.

 

Anisotropic Smoothing of the Skeleton

The one object that drives the Hairlock filter more than anything else is the skeleton image, which is capable of subtleties that even we don't fully appreciate. Interesting effects emerge when passing the skeleton image through the -smooth command, or, alternatively, Arto Huotari's Dream Smoothing filter. One goes for the extreme, setting anisotropy to one, sharpness to zero and large amplitudes (1000+) The thread-like artifacts which flow out from the ends of skeletal lines cause additional variation in the length of individual hair strands.

Repetitive Patterns: It's Not Just Hair

Using something like Inkscape's airbrush, which sprays an object with slight variations among scale and rotation transforms quickly generates skeletons for variational textures.
It helps to remember that “Hair lock” is just a filter name; we need not abide by the somewhat arbitrary limits imposed by such names. Hair can be grass. It can be spaghetti. Or a mop head.
We grew the grass in pretty much the same way that we grow hair; three plies, distorting the skeleton slightly with each pass, and varying hue, saturation, lightness, thickness and length.

Multiplying colored skeletons

When varying skeletons by warping or other means during the course of rendering individual hair plies, it is often useful to colorize the skeletons and set the composition operator of the layer to "Multiply" so that all skeletons are visible in an aggregate composition. This gives you a quick read on how the varying plies will interact with one another. The color of the skeleton has no bearing on the color of the hair, and so long as there is sufficient contrast, the filter will be able to detect edges in the skeleton and shape the hairlock.

A Pinch Will Do Ya

From time to time, you may wish to draw a strand of clustered hair to a point. There is no easy way to express this dynamic in the skeletal image. Fortunately the Distorts → IWarp filter helps, though a certain amount of care needs to be taken.

The game is to select a region around the ends of the hair strand you wish to adjust and then choose the IWarp filter. When in that filter, choose the Shrink tool and set a small Deform Radius (≈15) and a low Deform Amount (≈0.05) Stroke the strand, following its natural curl, so that it contracts toward the path of the tool's travel. To draw the hairstrands to a point, pull the Shrink tool slightly past the forming point. Just do one or two strokes, and then evaluate your results. It is easy to go overboard here and make a mess.

The issue with the shrink tool is that it is necessarily also a stretch tool, and this stretching induces a slightly blurry region around your work area. Notice the sharp spectral glints of two hair strands to the right of the path, near the arrow head. Note that as they were drawn toward the point they also softened, reducing the amount of the glint. In this case, the glint was just a little too harsh in the first place and softening it helped, but this is not a general rule.

The key is to work deftly and sparingly. If you have to work over too large an area, consider adjusting your skeleton instead.

Spread v. Skeleton

How much spread? How close should skeletal elements be spaced? Trick questions, these, because they're interrelated. These questions hinge on resolution.
If you just need a mass of hair and don't have much reason to worry about the intricacies of twisting and turning, then set spread to 0.7 or above and space skeletal elements as far apart as you can get away with. This is a very coarse resolution setting.
Sometimes, a wide spread away from a skeletal stroke gets in the way of other pictorial elements. Perhaps you need hair locks to curl just so and right there! These considerations all point you to a higher resolution setting. In this trend, you need to cut spread back and have more and more closely spaced skeletal elements.
Then there is the texture of the hair. If you need lanky, stringy hair, such as what afflicts some balding G'MIC documentation writers, naturally cut back on the spread regardless of the spacing of skeletal elements.
Spread seems to naturally decrease with age, at least with hair, and that is curious because with buttocks there appears to be an inverse relationship – but we're digressing, aren't we?

Garry Osgood