The Many Choices for Fur

Hair is a critical aspect of developing a character. Whether it be the protagonist, a villain, some random person on the street, or a dog in an alley, hair is everywhere. The importance of getting this right is reflected in the number of solutions that exist for this problem. I knew from the beginning that Suzy’s fur was going to take quite a bit of time to develop, but I had no idea it was going to consume this much development time.

From hair cards, to shell and fin techniques, to attempts at using parallax occlusion mapping, I have experimented with each approach to get the highest visual fidelity while maintaining acceptable performance levels.

Unreal’s new hair and fur system, which is featured in the image for this post, is the direction that I knew we wanted to learn going forward. This system allows developers to create near photo-realistic hair in real-time…with an experienced artist at the wheel, of course. My results are not quite there (some of the fur still looks a bit wiry), but I still have room for some fine tuning to get better results than seen above. But there is a catch to Unreal’s hair system. It is pretty demanding on the hardware, so an alternative is required for lower spec’ed systems. That is where the rabbit hole started.

You must provide an alternative character mesh for Unreal to show the player when their computer is not capable of running the hair and fur system. In my quest to do this, I started to create hair cards in Houdini only to see the triangle counts ballooning. Not only that, but hair cards have static textures for the hair color, among other things. So it was going to be very hard to get Suzy’s hair color right without an enormous amount of work. Seeing this techniques limitations, I chose to look elsewhere first.

Parallax occlusion mapping (or POM for short) seemed like it may be a fairly lightweight way of providing a hair material for Suzy. But after creating the texture sets needed and bringing everything into Unreal I quickly realized that POM wasn’t the answer. It looked awful.

Next up was the shell and fin technique that has been used with a high degree of success by others. After hunting around I found gFur on the Unreal Engine Marketplace. There is a free version that lacks grooming tools and some other quality-of-life features. But what do I need groom tools for? I have Houdini with a groom already prepared. I will spare you the pain, but getting that groom out of Houdini in a way that gFur will use wasn’t a turn-key solution, that’s for sure. You can see the results below:

Fig. 1: Suzy with the gFur plugin generating the shells and fins for her fur.

While the results from gFur look fairly good, and would look even better once everything was dialed in, there is a secret that the above image is hiding. At this distance from Suzy, there are over 800,000 triangles from the shells that are extruded and textured to fake the hair. Over 800,000! That is without the hair cards around her face to blend everything together nicely, and those cards would easily be 70-100,000 triangles. Maybe I am doing something wrong, or perhaps this isn’t going to have the impact on performance that high triangle counts used to impose. But, this doesn’t feel like the solution I had hoped for, so back to the hair cards I went.

As stated above, one of the major problems with using hair cards for Suzy is her hair color. Or should I say, colors. With characters where their hair color changes from one location of the groom to another, it presents a challenge to create texture sets that will work correctly without having to generate many large textures to represent the subtle color variations. This is a lot of work and eats away at VRAM that is certainly needed elsewhere. My solution was to take the color values from the hair groom created to export to Unreal, and ‘push’ those values into the hair cards vertex color values. This was very challenging because I am still very new to Houdini and hadn’t worked with VEX before. VEX is a C-like language that can be used in Houdini to write snippets of code to automate a task or change some values programmatically. With that, I was able to get the groom’s colors and place those values onto the cards. So, if the hair color texture changes no extra work will need to be done for the hair cards or the Unreal hair groom. Just a simple re-export is all that will be necessary. You can see a cropped image of the hair cards below:

Fig. 2: Suzy’s hair cards complete with vertex colors that can be used in Unreal to tint the hair texture. The hair color texture is applied to the mesh, and then ‘pushed’ to the hair groom itself (not shown). Then, the hair grooms color values a ‘pushed’ onto the hair cards themselves. So the cards truly reflect the grooms colors.

The image above shows Suzy with her hair cards without any type of material applied. The color that is seen above is all driven by the vertex colors on the individual hair cards. With those vertex colors, I should be able to tint the base color values in Unreal’s material editor to get a nice transition of colors without having many different texture maps to achieve a similar effect. The down-side about this approach is the number of triangles. The above hair card groom is around 650,000 triangles. This can be controlled through level-of-detail (commonly known as LOD) meshes which Unreal does a great job of creating for us, but that is still a high number. I have no idea what effect this will have on performance.

The moral of the story is that hair is a challenging subject to take on. No matter what we do, there will be performance trade-offs that have to be made. And artistic trade-offs as well.