Wrinkles!
And nary a tension map in sight. I started getting somewhere with @shteeve’s add-on, but along with a creasing problem (which I now suspect is due to linear vertex group falloffs - see my closing paragraph below) I found I couldn’t get enough sensitivity out of it without the “spread” variable discussed in the comments on RCS. So I’ve reverted to plan B for the time being, which up until recently was just a crazy untested theory.
Plan B consists of the same dual height map setup I was using before, but instead of activating parts of the images automatically using tension, I’m using masks driven directly by the shape key values.
The maps are baked from sculpts, and there are two of them, to account for wrinkles that cross over other wrinkles, e.g. vertical frown lines vs. horizontal raised-eyebrows lines. There may need to be a third, to cover special cases like “worry”, which diverts the direction of the lines into a different shape on the forehead.
For each shape key there’s a mask image that reveals a portion of one of the wrinkle maps. I’d have used Vertex Colors instead of images, but for some reason there’s a limit of eight (and I’ve already used up four of them for other things). Behold the spectacular majesty of the “Nose Sneer L” mask:
In the nodes below, the Nose Sneer L shape key is driving the Value property of a Math node, which changes the intensity of the Nose Sneer L mask image. This is sent on to a MixRGB node where it’s combined with the other masks. Here it’s being mixed with the Right Nose Sneer, which uses the same mask image flipped horizontally by scaling X by -1.0 in the Mapping node. This minimises the number of mask images needed, and automatically mirrors any mask edits to the other side of the face.
The face consists of a whole battery of these nodes daisy chained together and mixed with Wrinkle Map A, and then run into a displacement node that’s mixed with another battery of nodes controlling Wrinkle Map B:
The hardest part of this was mixing the masks in such a way that they don’t cancel each other out, double up where they overlap, or deliver the wrong displacement Midlevel value. Key to this was to use Screen blend modes to mix the masks, and to add the A and B maps together after displacement instead of beforehand. It’s not quite perfect though, and no doubt there’s a well established “proper” way that someone will care to enlighten me about.
Clearly this setup is a lot more cumbersome than tension maps, and I haven’t even started on finger joints and other bendy body bits yet. It’s not quite as organic as tension maps either (something as simple as this would be a challenge), and I have to approximate the areas of influence rather than relying on tension to automatically generate them for me “correctly”.
On the other hand it works in vanilla Blender (even 2.79), and there’s more control over the wrinkles, even if it’s less accurate. Ultimately though this is just a stopgap, until tension maps are a workable option.
In preparation for the wrinkles I had to refine the shape keys and reconfigure parts of the rig, as well as redo the eyebrows so I could see where they were in relation to the wrinkles, since the hair particles had lost their symmetry and started to stray (along with the eyelashes). I revitalised the skin as well, since it had lost its lustre at some point.
And there’s something else you might have noticed…
This is an interior “skull” structure onto which the head is shrinkwrapped, and onto that I can sculpt bony landmark definition for the skin to slide over (the features are exaggerated somewhat for the purposes of this test).
I’m gradating skin thickness by using vertex groups on the exterior object, however there are creases which I think are caused by the linear falloff of the vertex groups between polygons. So far it’s subtle enough that I can get away with it (with the help of some surface texture), but I have further plans for this that might not be so forgiving…