Ronan Mahon talked about the way he worked on his Fabric Materials Collection for UE4 with Substance Designer, Adobe Lightroom, Adobe Photoshop, and scanning.
How it Started & Goals
My Fabric Materials project started out of necessity. After 7 awesome years with Rocksteady Studios in London working on Batman, I moved with my small family to Germany to start my own business. When you work for yourself you realize how much you took for granted the great tech, licenses, and subscriptions that come with working for a AAA studio. As an independent developer, I no longer had access or the budget for all of these things but I had some ideas. I planned to create an AAA quality asset store for game art and so I needed the raw materials (pun intended) to do so.
I had seen this great tutorial by Allegorithmic (Your Smartphone is a Material Scanner) a while back and wanted to give it a go. My first few months as an indie developer in a new country you would see me with scissors in hand and Substance Designer in the other, and a new baby in the other-other!
After much trial and error, I made my scanner out of IKEA products, a lazy susan and some cans of spray paint. My father in law has a great workshop so the two of us set out to construct the lightbox necessary for scanning fabric properly. My German is very basic so I’m sure he was pretty confused by the whole project! I ordered a simple backdrop from Amazon and with my trusty old Canon 600D, I now had all of the pieces I needed to start scanning the fabric. The whole setup probably cost me under $150, with the most expensive parts being the LED lights and the backdrop. My new scanner had a material scan working area of 25cm² and could double as a 3D scanner for objects such as statues etc up to 75cm tall.
My first scanning test samples came from cutting up the in-laws clothes. Needless to say, I needed another plan. I went to a tiny local sewing shop in the German countryside and my embarrassed wife translated that her husband would like a little bit (25cm² to be exact) of everything. Living the dream!
With these samples, I was able to work out the pipeline needed to get a top quality result in Unreal. The pipeline is the following:
- Live Capture in Lightroom with Cannon, Magic Lantern & Auto Exposure to the Right to get as much data as possible. Live shooting with manual focus to get as sharp shot as possible. Color calibration with X-Rite. In order to generate a normal map, you need to capture 8 input images where the light is shone on the fabric in 45° increments. I achieved this by placing the Lightbox on a turntable (IKEA Snudda lazy susan!)
- Adobe Lightroom for lens correction, color correction, and image development.
- A simple batch action created in Adobe Photoshop to crop, rotate, register the images accurately and export the end result.
- Scan processing in Substance Designer and export of textures to Unreal or another engine.
About Seamless Materials
To make a good tiling and seamless material from a scan takes a bit of trial and error. First, you need to get as clean and straight a scan as possible. I ironed all of my samples and brushed them with my baby daughters tiny hairbrush to get the best result! If you take some time at this stage you will thank yourself later. You also need a big enough sample so that you’re retaining enough raw scan while not having to clone the original too much to fix issues. To make good fabric you also need to capture the opacity of a sample. This is done by shining a 5600K light evenly through the material and capturing the result as an opacity map.
Substance Designer comes with all of the tools necessary to process your sample into a tiling material. My graph is based on the example from Allegorithmic with a few custom bits thrown in. Here is the graph process:
- Crop your 8 input images and your Opacity as large as you can to preserve your raw sample while cutting off the unnecessary edges
- Create your normal with the Multi Angle processing node
- Clean up your Basecolor and clone out any small issues in the material such as blotches or an unwanted wrinkle that would cause tiling problems
- Use the awesome AutoTile node to make your scan tilable. This node has a lot of controls so you should spend some time here to find the largest and best sample needed to create the tile. Check the result on the 3D view and with higher tiling values in order to spot tiling issues.
- All of your other texture maps such as roughness, AO, Height, and Subsurface can now be derived from these tiling maps
- I made a custom exporter node to give me maps in all the various texture formats I need as well as doing checks like making sure all the values are in the correct PBR range. (See the PBR Guide by Allegorithmic for more in depth info about the Roughness Metallic workflow and important values)
Adjusting realistic Material Properties
Having the fabric material in my hand was key to a convincing end result. Some of the information is captured directly by the scanning process: BaseColor, Normal, Opacity etc. The rest of the material properties are achieved through observation.
For roughness, I started with the great DONTNOD guide as a rough idea for where my values should lie. I then compared each fabric to the other and picked a value that matched closest to what I saw. I used a curvature map to subtly modulate the roughness value.
I adjusted the specular level around the 4% reflective based on observation of the material under the light. This is a very subtle adjustment for dielectric materials.
During my capture process, I remapped my Opacity texture 0-255 in order to get as much information in the texture while also making it more general use for other materials. In Unreal I used this texture to either drive the Subsurface Color or the opacity of the fabric. By holding the fabric up to my window I was able to observe again how relatively opaque or not the fabric was in relation to the other samples as well as how much influence and how high contrast the fiber structure appeared to shine through. I built in some simple material parameters to tweak the final result.
What I also observed while having the fabric to hand was that some of the specular of the fabrics appeared colored. This was probably due to the inclusion of metallic fibers in the material. I was then able to account for this in some of the satins and cotton fabrics.
Coming from a background in games I’m aware that “Translucent” transparency can cause a lot of issues in rendering. It can be expensive for performance on consoles as well as cause depth sorting issues with other translucent objects such as particles and other VFX. For that reason, I went for the more performant option of using the “Masked” blend mode in Unreal. This blend mode has the benefit of being very close to an Opaque shader in performance terms as well as being able to cast proper shadows which account for the transparent parts of the material.
The downside of using “Masked” is that it makes your opacity mask binary (either a value of opaque or transparent) and so you can end up with a material which looks low res and jagged around the edges. To combat this downside I used the post process effect of dithered Temporal Anti-Aliasing in the material. This post process softens the jagged edge and results in a convincing look without the issues I mentioned when using “Translucent” blending.
Fuzzy Shading is a node which comes with the Unreal Material Editor that allows you to fake the look of a fibrous surface such as velvet or moss. When you observe fabrics with little loose fibers such as wool you will notice that the surface tends to get brighter toward the edges (normals perpendicular to the camera) and darker in the core (normals parallel to the camera). This effect is similar to Fresnel and it’s vital when trying to emulate fabrics. Having the materials and bunching them up in my hand I was able to see relatively how bright or dark I should make them and what settings I should use on the FuzzyShading node.
Fabrics with a deeper pile such as wool appear much darker when viewed face on due to the long fibers. It’s a bit like looking down on a forest of trees with a dark forest floor. Interestingly with some of the fabrics like rayon, I observed the reverse, a light center with a dark edge. This was interesting and probably due to the fibers being shaped and aligned in a single direction. Incidentally, I used the FuzzyShading node within my Subsurface material rather than use the “Cloth” Shading Model because it allows me more freedom – “Cloth” doesn’t have Subsurface Color options.
Improving the Collection with Material Functions
When I initially released the fabric collection on the Unreal Marketplace I received some great suggestions for improvements from the people who bought it. One of the users mentioned that he used a lot of blend shaders which combined two or more materials using blending in the material editor. My original release works well with materials and material instances – but it didn’t really support material blending. I thought this was a great idea and in order to support this workflow, I completely remade a new variant of the entire library structure using Material Functions. The power of Material Functions is the ability to pack a whole material into a single node. These nodes can then be easily blended together in the Material Editor in a myriad of ways.
I hadn’t done much work with Material Functions before and they presented their own unique challenge in order to present a user-friendly package. For the Unreal Engine free month promotion I released version 1.1 of the fabric collection which includes this new Material Function library. I also took the time to preserve the control and structure you get from a Master/Child relationship between the functions. Even with this Material Function variant you can still make large changes to a whole subset of materials or just edit an individual child instance. Also included in this release are several examples of how to use the new functions – vertex painted blends, blends driven by blueprint and complex animated masks.
What I ended up with after the hard work which went into this fabric collection is a pipeline that can create a 4K PBR material with all the bells and whistles in under an hour from start to finish. Working with the materials in my hand also gave me an appreciation for all their properties and imperfections. It was fascinating to see how light reacted and traveled through certain samples. To top it all off – my German in-laws think I’m a bit strange and I could also get a job as a network engineer if this whole art thing doesn’t work out.