The Surcoat2Hair Macros

Scripted by Tim Nikias Wenclawiak - Homepage: www.NoLights.de

Last update: 28.06.2008

Contents
Introduction
Technique
Usage
Hairstyles and -colors
Hair-Parameters
Customizing the hair-macros
List of Macros

This set of macros provides several means to visualize sample-sets generated with the Surcoat macros with hairs. There are four possibilities to do this, so you should choose whichever best fits the current project.

In regard to copyrights: this set of macros was written by me in my spare time. All I require is that you give credit where you feel credit is due, and drop me a note to let me have a look at what you've achieved with my macros. :-)
If, however, you make money with them, that's a no-no without my consent!


The crude approach anyone would take when creating hair, is to simply generate and place a hair per sample. Depending on the complexity of the hair and the amount of hairs total, this process can take quite long and will also require lots of memory to store all the hairs.

I've considered this and found that this is actually overkill. For one, unless you truly simulate the hair-hair- or hair-object-interaction, hairs will look the same whenever they are pointing towards the same direction. As interaction between hairs and objects can be ruled out for POV-Ray applications simply because of the time required to actually simulate all the dynamics, this was the first goal: instead of regenerating the same hairs over and over again, I wanted to reuse those that I've already got.

But instead of simply generating hairs by need and reusing them where possible, I've reversed the process somewhat: I first generate a good selection of hairs, and then only pick from them. In order to match slightly different hair-normals, I calculate the difference and convert it to angles. These angles are then used to realign the hair.

The same approach is applied to the length of the hairs: instead of generating all kinds of lengths, I generate a set of for example 5 different lengths, and just pick those that match the current need the closest. But does this really help memory consumption? Only if you are using meshes. POV-Ray won't place another copy of the mesh into the memory, but instead only a reference (in programming terms, a pointer) to the mesh. The pointer has a given size of its own, but it is still smaller than another mesh. If you're using CSG, e.g. cones and spheres, to generate the hairs, then the entire speed-up doesn't make that much sense memory-wise. The Sc2Hair-Macros come with a mesh2-generating hair-macro.

So how do you define the amount of hairs? Think of a cube, divided into even parts, e.g. 5x5x5. That'd be 125 entries. Now, remove those that aren't on the outside of the cube, that'd be 3x3x3=27, so you've got 98 entries left. This is the amount of hairs generated if you select a cube-length of 5. I've coined this cube the ICube, as it provides the basics for the interpolation of hairs. Also, to keep the usual term for hair and the one used for the interpolated hairs distinct, I've coined these the IHairs.

Now, once we have the basic set of 98 IHairs, this value gets multiplied with the amount of different lengths we want to have. If we choose 4, we end up with 392 IHairs. That is already a pretty suitable set. Of course, this depends on how thin the hairs are, how many are placed, how the topology of the object is, but in general, you can get away with less than half the amount of placing a hair per sample and still have the same quality.

To generate the IHairs, there are several possibilities, of which some include writing the IHairs to disc. This you can do to later reuse the same hair for other scenes or simply to save parsing time on successive renders.

A final note in regard to animations: the IHair-Technique isn't suitable for animation. Why? Well, if the normal of a certain hair changes during the animation and requires a different hair, the switch from one hair to the next will be sudden and obvious. Nontheless, there is one macro which will generate one hair per sample, so if needed, that macro can be used for animations. Note though that the memory consumption will rise drastically!



There are four ways to place hairs onto the samples, but one word up front: there's a parameter called Sc2Hair_YSwitch, which is set to off by default. It has the following effect: if set to "on", a hair which is placed with either (y)- or (-y)-normal will be rotated by a random amount around the y-axis (hence YSwitch). This is done because the hair at that normal will always be bent forward towards -z. In effect, if you'd apply this to a plane, all hairs will "look" towards negative z. So, to work around this, you have a choice: either use an ICube-Resolution which doesn't generate a +/-y hair (ICube-length has to be an even number then), or set the switch to "on". Note that this will still be an issue on planes (as the macro will always choose the same hair when confronted with +/-y) but on slightly curved surfaces, even ICube-Numbers are handled better. But now, to the visualization macros.

First of all, there's the macro called Sc2Hair. It takes the Sample-File and two UV-Vectors as parameters. The first UV-vector defines the Base- and the Tip-Radius, the second UV-vector defines the minimum and maximum length of the hairs. The macro will then generate a single hair *per sample* and not save anything to disk, as this can result in huge files very easily. Most of the time, you'll be wanting to use this macro only for a final render (though a high-res for an ICube might be sufficient, but that's up to you) or for animations.

Then there's a two-step method which again, won't save anything to disk, but at least settle for less memory consumption. First, Create_IHairs declares a few arrays which store the hairs. Second, Sc2Hair_UseCreated will then visualize the samples with the declared hairs. Create_IHairs takes four parameters, first, the ICube-Size (3 and higher) and the amount of different lengths to be generated when the minimum and maximum length aren't the same. Finally, the two UV-vectors for radii and lengths. Sc2Hair_UseCreated will only require the sample-set-filename as parameter.

Third, there's a macro which will not only generate the IHairs, but also save them to disk for future use. The macro is called Write_IHairs and requires just an additional parameter along with the four mentioned paramters for Create_IHairs. That fifth parameter is simply the filename to which the IHairs shall be saved. The macro to make use of saved IHairs is simply Sc2Hair_UseSaved, and it requires two parameters: the filename of the sample-set, and the filename of the IHair-Set.

And finally, there's Sc2Hair_OnTheFly. It will require 6 parameters: the sample-set, ICube-Size, Steps in Lengths, UV-Vectors for radii and min- max-length, and a filename to write. What the macro does is to generate only those IHairs that will actually be needed for the given sample-set. For example, it might be that all hairs pointing downward will be short, whereas those pointing upwards will be long. There's no need to generate long, downward-pointing IHairs then. The resulting file can be used with other sample-sets when combined with Sc2Hair_UseSaved, but since some IHairs will be missing, other sample-sets might have "bald" patches. Generally, this macro is meant to be applied to a single set of samples, but a higher amount of IHairs can be picked for better detail without actually creating all IHairs.

Another macro is provided, just in case you (for some weird reason) need to place a single hair somewhere: SingleHair, which requires Position, Normal, and an xyz-vector: x is the length, y the base-radius, z the tip-radius.



It would be pretty boring if the hair always has to point away from the object like a surface- normal, and if the hair's color wouldn't be very flexible. There are thus two macros (and a switch) to take care of this. You'll have to declare and script the macros to your liking, there are just a few rules to follow for them to work properly.

Modify_IHairSample will receive the hair's position, the normal, the length and a UV-vector for the min- and max-length-values. Using this data, you may re-declare the position, normal and length by using #declare inside the macro. Generally, what you will do is amplify the normals along a certain axis, e.g. the x-axis, to have a more spread from right to left, or you will want longer hairs on the top of the head, so you will derive the length from the y-position of the hair.

Then there's Sc2Hair_Texture, which will get the hair's position, the original normal, the normal it got after Modify_IHairSample was called, and the hair's length as parameters. Using those values, you may return a texture-statement which will be applied to the hair. Note that my hair-macro has uv-mapping, so if you put the uv_mapping-keyword into your texture, you can easily achieve effects like changing the hair's color from base to tip. Note that this macro will only be used if Sc2Hair_IndividualTexture is set to true/1/on. Also note that if you want to have all hairs use the same uv-mapped texture, you can simply apply the texture with enabled uv-mapping to the entire union of hairs, instead of texturing every hair by itself (which would be require more memory).



The hairs are an optional (though default) and exchangable part of the Sc2Hair-System, and thus don't use the Sc2Hair-Prefix. What follows is a short description of each parameter with it's default value and it's use.

Hair_Gravity (-y) Sets the "pull" direction of gravity
Hair_Wind (<0,0,0>) Sets the direction and force of the wind
Hair_WindStrength (.7) A modifier for how much wind affects the hair, lower values lead to stronger, more wind-resistant hair

Hair_FixedSteps (on) If "off", the steps along the length define the amount of steps per unit- length, and are thus not a "total" number
Hair_Steps (<8,15>) Sets the steps along the radius and along the length of the hair, with above mentioned switch
Hair_BentPerUnit (60) The hair is generated with angles as base, and this value sets the maximum bending applied to one unit-length of hair due to gravity (wind is added *after* this has been checked)

Hair_BaseStretchRatio (1) May be used to "stretch" the hair at it's base
Hair_TipStretchRatio (1) Like above, but for the tip



The hair-macro I've supplied, though it does have a few neat features like wind, uv-mapping and smooth-triangles, is only very basic and just allows simple bent hairs, for example, curls aren't possible at the moment. The hair-generated is split into two parts: first, I generate a simple line/spline, along which the hair will be generated. If you'd want curls, this line would have to be curled, which I didn't implement to keep things simple for starters (and because I didn't have the time nor need to do so). The mesh2 is generated by another macro which will simply move along that line and model a "tube" around it, using the radii supplied by the User.
So, even though some things are possible, there are limitations to the current hair-model. It might be that you've got a nice and running implementation of your own you'd like to use, or that you just want to enhance my macros with more features. In any case, it's good to know where to start "modding".
There are three macros which will eventually call, generate and return a hair. These are Create_IHair,Write_IHair and OnTheFly_IHair. They simply return a mesh2, write a mesh2 to file, or do both, respectively. If you want use your own hair-macros, simply redeclare these macros *after* including "sc2hair.inc". You will thus overwrite my macros and the system will make use of yours. For further details, look into the Include-File, these macros are conveniently saved close to the top of the file. Another note: I've written three macros to create and/or write the hairs. It would also suffice to have one macro generate a mesh2-object and one which will write a mesh2-object. OnTheFly_IHair could then simply call both of these. I wrote another macro for that to save some parsing time, as the creation- and writing-step make use of exact the same algorithm, and I could save a double pass on the same data to create the same result...



Sc2Hair
(Surcoat_Sample_File, <Base_Rad,Tip_Rad>, <min_Length,max_Length>)
Will place a hair per sample, no written files are generated. Very memory expensive.

Create_IHairs
(ICube_Length, Length_Res, <Base_Rad,Tip_Rad>, <min_Length,max_Length>)
Creates a set of IHairs in the memory which will be used by Sc2Hair_UseCreated. A new call of Create_IHairs will overwrite the current ones. No files are written to disk.

Sc2Hair_UseCreated
(Surcoat_Sample_File)
Will place the IHairs generated by the last Create_IHairs-call. No written files are generated.

Write_IHairs
(ICube_Length, Length_Res, <Base_Rad,Tip_Rad>, <min_Length,max_Length>, IHair_File)
Writes a set of IHairs to disk, which will be loaded and used by Sc2Hair_UseSaved. The main purpose is of course to parse and create hairs once, and then just reuse them...

Sc2Hair_UseSaved
(Surcoat_Sample_File, IHair_File)
Will place IHairs from the IHair_File. If the same IHair_File is reused, the file won't be included again. This only works if you don't rename the IHair-Files, as they save a variable with their name for exactly this check.

Sc2Hair_OnTheFly
(Surcoat_Sample_File, ICube_Length, Length_Res, <Base_Rad,Tip_Rad>, <min_Length,max_Length>, IHair_File)
Will write the IHairs needed for this sample-set to disk. The file may be used by Sc2Hair_UseSaved, but may contain bald patches if IHairs are required, for which the IHair wasn't created. Best used for a single sample-set with higher detailed ICube-Settings.

SingleHair
(Hairbase, Hairnormal, <Length,Base_Radius,Tip_Radius>)
Will generate and place a single hair.

User Definable

Modify_IHairSample
(Position,Normal,Length,Possible_Lengths)
May be declared to alter the position/normal/length of the hair. Especially needed to create hair of different length, otherwise, the visualization macros will only use the shortest possible. Simply #declare the parameters in the macro to change them.

Sc2Hair_Texture
(Position,Original_Normal,Modified_Normal,Length)
May be declared to texture each hair individually based upon the given parameters. The macro is supposed to return a texture-statement. Only used when Sc2Hair_IndividualTexture is set to true/1/on.