Hey everyone, my name is Ellie Porfyridou, I am from Greece and soon to be graduate from Howest Digital Arts and Entertainment in Belgium.
During my studies I have worked on various projects, from hand-painted low poly weapons to modular levels in Unreal, as a result, I could expand my skills and decide on what I enjoy doing most.
I have always been identifying myself as a gamer, but now I can definitely say that I love making games more than playing them.
For my graduation project I chose to research into real-time hair techniques used by developers nowadays, this subject seemed quite challenging yet fascinating enough to keep me motivated for the next six months. Having analyzed some of the most successful next-gen games I concluded that for 3D characters starring in AAA titles, artists use the method of alpha blending cards for hair creation. Polygonal cards with a diffuse texture of hair, generated or hand painted, and an alpha map for transparency are laid on top of each other to form the structure of a hairstyle.
There are a lot of ways to create the texture, fibers could be drawn by hand in Zbrush with a Curve brush or rendered from fibermesh, could be painted in photoshop or generated in Substance painter as seen in this cool example by Chang-Gon Shin.
For my project I wanted to try Xgen, I’ve encountered some incredibly realistic hair examples from other artists created with the plugin while researching and I wanted to get more familiar with Maya.
Working with XGen
First, I created a new description and placed a few guides on a slightly tilted simple plane and gave them a bit of a shape with the sculpting tool. After that, I adjusted the density, the length and the width of the fibers. Hair usually is thinner at the tips, to achieve that I altered the curve of the width ramp and tweaked the taper values until I got the result that I wanted.
Next step is to transform the “CGI” looking strand of hair into something more realistic. In the modifiers tab of the Xgen editor, there is a collection of various kinds of modifiers that could be added to achieve that. Since natural hair tends to grow in clumps, the clumping modifier was the most important for my workflow, I used several on top of each other, changing every time the maps that determine each time where the clumping is going to happen and the intensity of the effect. Cut modifier makes the tips of the hair uneven as in real life. The Noise modifier gives the finishing touch creating waves along the fibers.
While keeping an eye on the references I have gathered for the specific hairstyle, I continued by creating some more planes with different strands for hair variation, one strand for the flyaways and a couple for the short transitional hair.
Arnold Renderer is free to use under educational license and integrated into Maya, in addition, there is a great dual scattering shader for hair created by Anders Langlands.
There is a detailed tutorial that explains how the shader works and how to set it up to get realistic looking hair as a result:
I followed it to render the diffuse texture in orthographic front view.
One of the problems I have encountered while working with Arnold is that sometimes after changes in the scene, the renderer wouldn’t update automatically, to solve this issue I had to force the update manually by pressing CTRL + U combination.
I intended to utilize the Unreal hair shader in its original form as included in the Photorealistic Character project in Engine Feature examples, for that, I needed to create the additional maps such as depth, Unique ID and root map.
Root map is a simple gradient to specify the root region. Depth texture creates the illusion of pushing the hair deeper into the hair volume. The Unique ID texture assigns a unique black to white value for each fiber of hair, as a result, hair gets a slight variation within itself.
Xgen descriptions had to be converted into actual geometry to bake the textures onto a flat surface. Using the option Convert Xgen primitives to polygons in the Generate tab, my fibers turned into the high poly mesh in no time. Once you have sorted out the high poly getting the base textures is a quite straightforward process. I created a simple plane with the appropriate dimensions which I was going to use as my low poly mesh and exported everything as obj files. Andrew Giovannini has an excellent video tutorial on how to bake all the necessary textures using xNormal tool.
After the textures were done I made the actual low poly cards, UV’d them and assigned the diffuse texture to visualize the hair.
I imported the head mesh and started the process of duplicating and hand placing the cards layer by layer depending on texture opacity. For example, the base layer is used mainly to cover the scalp and has the opaquest texture assigned on while next layers are more transparent, this way the hairstyle has more depth.
For the braid element in Zbrush, SK_Hair brush by SAKAKI Workshops that creates teardrop shape was used to form the base mesh. It was then imported into Maya, where I placed the UVs on textures used for the base layer. Duplicated the braid a couple of times and moved the UVs on more transparent texture each time. Building up hair mesh with this method helped me to create volume in my hairstyle.
Finally, I added the flyaways layer, it breaks the silhouette nicely and adds the finishing touch of realism. I was looking a lot on my reference pictures to place that kind of hair correctly.
I was working in the smooth mesh preview mode in Maya, it allows you to manipulate the cards easier without adding a ton of geometry. Once I finished with the hair I converted the preview to polygons by using Smooth Mesh Preview to Polygons option in the Modify tab. I ended up with a high poly hair around 75k faces which cannot be used in real time environments. In the Mesh tab there is a function called Reduce, I used that to achieve a lower number of triangles needed for a game ready hair mesh and exported everything as an fbx file for the next step.
I had some troubles importing the fbx in UE4, tried several format versions but nothing worked. Until I realized that maybe the scale was causing problems. As it turned out my mesh was way too small and was causing issues while was imported into Unreal.
In UE4 I made an instance material of the master hair shader and replaced the maps with my own. Then I tweaked a lot the values of options such as roughness and scatter until I got the result that I wanted. Adjusting the Pixel Depth Offset helped me blend the strands and fade out some of the intersection points of the planes.
I worked for the whole semester on my project, but everything can be done a lot faster once you establish a workflow and you know what you’re doing. I spent quite some time researching techniques and methods. Also started with a simple hairstyle at first to try out the pipeline and only after moved on to a complex one. It was an interesting journey, I learned a lot and intend to do more hairstyles in the future.