The Surcoat2Hair Macros
Scripted by Tim Nikias Wenclawiak - Homepage: www.NoLights.de
Last update: 28.06.2008
Contents
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_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_BaseStretchRatio (1) May be used to "stretch" the hair at it's base |
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. |
Sc2Hair Create_IHairs Sc2Hair_UseCreated Write_IHairs Sc2Hair_UseSaved Sc2Hair_OnTheFly SingleHair User Definable
Modify_IHairSample Sc2Hair_Texture |