Charlie Foreman explained step-by-step how he created a procedural layered wall material.
In case you missed it
You might find these articles interesting
Hi everyone. My name is Charlie Foreman and I am currently a Material Artist at Sony VASG. I’ve been in the game industry for about a year and a half as of writing, previously working as a contract Environment Texture Artist for Naughty Dog during the production of The Last of Us Part 2. In my spare time, I mostly play video games, cook, and make materials in Substance Designer.
With the current world affairs going on, I’ve found going for walks has been a huge part of keeping my mental and physical health well, and of course for finding some nice references for personal work! One such wall in the alley behind my apartment caught my eye a few months ago, and finally, I had decided to give it a try in Substance Designer.
This wall had a lot of strange and interesting elements that made me really drawn to it. Even the most mundane materials in everyday life with enough wear and tear can show their true colors. With multiple different components embedded inside, it was time to get to work.
Alley Wall: Planning the Project
When looking at this project, one thing I noticed was how the different components all worked together. The wire was not a normal rebar that was often seen in concrete walls, but rather a small chicken wire with very thin wooden planks for support. However, it looked to me that the best way to do this material was going to be to have two planes and the wire on one plane while the tessellated geometry of the wall itself was sandwiched between the two, to give the wire some depth.
However, I opted against doing so because I felt like this was a good way to practice material layering. This is something I didn’t have many examples of in my portfolio, and there were many upsides of doing it this way. I could remove any of the layers of the material and be left with 3 main components. The concrete, wood, and wire. Doing them in subgraphs and blending them together was an option, but I generally like to keep everything in one sbs file if I can help it, and the material didn’t end up being too complex.
Afterwards, it was time to highlight different details in my reference images to best understand how my components were going to be laid out. By sectioning off these individual micro-mid-macro details, I’m better able to get a grasp on what I need to accomplish in the graph.
A crude paintover of the components is a simple yet effective way of creating them. I worked from the interior to the exterior since it’s much easier to create the components in a layered order, so you can build each one on top of the next.
I’ve been trying to keep the graphs more uniformly organized whenever I make materials nowadays. It makes it easier to tweak them back. Usually, when creating them, they’re clean, but when I go back for revisions it usually becomes a big spidery mess.
As discussed before, each component gets its own section of the graph, where they all blend back to the main line before splitting off into my outputs. When creating materials, it's important to be able to get masks for each detail for color/roughness. In addition, materials will need to be easily adjustable with as few nodes as possible. This will speed up creating iterations. Usually, I try to make it so that changing the base nodes (such as a Cloud noise I’d use for masking/a Tile Sampler) will give me the desired effect.
The bottom-most layer of the wall material was the wood that laid underneath it. Since it had more components in and of itself, I split these node families up into their own little sections so I could easily connect them all to one another.
I started with a Tile Sampler node which I used to create a Flood Fill mask for height variations. This will help add the subtle detail of height difference in the planks but also be useful in the color map for down the line. When I make a texture, I like to split off nodes I think I’ll be using for masks with a random node (usually Blend or Levels) and just put it at the top of the graph to move later. With a Tile Sampler, I can adjust the number of planks showing underneath, allowing for quick scaling information.
Next, I use a Distance node to help close the gap between the planks while adding a slight beveled effect. Normally, I see this node being used to create Voronoi patterns and Cells, but I’ve liked using it as a bevel/blur alternative recently. Using my mask from before I multiply it over my planks with very low settings and then blend a Slope Blur version of the planks over itself. Since this material is going to be at the bottom of the height map, I can be a bit harsher with my values since they will be clamped to dark later.
The next component of the wood I completed was the grain.
Using an Anistropic Noise as a base and a Gradient Dynamic with a Gradient Linear 1 plugged in will get a swirly sort of ‘grain’ pattern, like when you normally look at wood and see how the fibers spiral. Make sure to set the dynamic to vertical for the result to properly show. I blur it, swap its direction, and then Directional Warp the pattern with my flood fill mask to help break it up among each individual plank.
Using a Tile Sampler, I can randomly pick spots where knots will show up. I simply blur those spots with the setup above, warping the initial fiber pattern before using the same Gradient Dynamic trick I did before to blend the fibers onto the wood.
Afterwards, I blend a fibrous noise pattern over my custom gradient fiber pattern and then Slope Blur with it. This gets me a gritty look but overall, the design I want.
I also do a minor peeling effect for some splinters of wood that are upheaving in the wood. I make a histogram clamp on a Clouds 2 and then Non-Uniform Blur the result. Then by subtracting the Histogram Scan mask and the blurred one, I get an upended edge. I warp it with my plank flood fill mask again before Slope Blurring with the fiber patterns.
For the rest of the wood, I use a few Tile Sampler nodes and then Slope Blur their results. The details will be so small that I don’t need to do much else. I blend on a Dirt 2 node as well since it’s a great lazy node for adding a few bits of bumpiness without seeming too homogenized. The cracks are made from just clamping a pair of vertical grunge maps. Everything gets subtracted from the overall height of the planks.
Again, a good reason to work like this is if the other component materials are removed or hidden, the artist has several solid materials to use individually, rather than just one big wall.
By the time I’m finished with the wood, a lot of the details have now been brought down to a low greyscale value. They will get even darker when I begin to layer the materials together, so I tried to keep a good range. If it doesn’t look right, you can intensify the amounts used per node. I didn’t include individual numbers because part of the magic of Substance Designer is discovering your own values and what works best for you given the situation.
There were these strange pieces of cloth-like support that were behind the wire, so I decided to include them in the material as a detailing piece. They seemed to be held down by the wires when the wall was in place, but a lot of it had been torn out.
To set it up, I repeat the exact process I did for my flaking splinters on the planks before, but using a different random seed for the Clouds 2.
Afterwards, I a pair of Tile Sampler nodes mixed together to get a crisscross for the fiber pattern. Too subtle probably but even the micro noise to reflect roughness in the final product would be appreciated. I blend that over the clamped histogram which I lower with a Levels node. This lets me blend a few variations of Perlin Noise over the entire thing, giving the illusion of the material being warped and puffy. The crisscross of Tile Samplers is then blended on top.
I also use my plank mask to subtract from the cloth, but only slightly. This allows for it to not be uniformly placed over the wood and sinks into the dents.
Finally, I layer a Perlin Noise over the edges of the cloth, using my initial setup with the upturned folds as the mask to help make the edges not all rising to the same uniform height.
To add them together, I do a Non-Uniform Blur with my Histogram Scan mask and then simply Blend the cloth on top with Add. If I need to adjust the overall height of the cloth, I can adjust the white values from the Levels node I mentioned before.
The next component to handle was the wires. This was a bit of a challenge because in my reference they were tangled together in this massive conflagration of wirey death. So, I decided to just have it more frayed near the end.
I use a Waveform shape and then run it through an Edge Detect, snipping off the edge with a square Shape and then running it through a Non-Uniform Blur to give it a little volume.
Something I don’t see used as often as it should be is using Blend nodes to mask off individual sections of a node if you adjust the Top, Bottom, Left, and Right settings. I set my Top to .5 to erase the bottom half. Afterwards, I snip them apart using Transform 2D and Non-Uniform Blur which is essentially ‘welding’ the edges. This is so when I overlay this shape together, when the edges meet, the wires will overlap and cross over one another. I run it through a Tile Sampler and presto, we have a pattern intersecting.
The blur isn’t clean, but it will not be noticeable in the graph as it will be clamped out, and now the wires are properly interconnected.
I take another Tile Sampler and then run it through a Flood Fill and then Random grayscale. Using a Distance node, I’m able to create a randomly generated panel of checkers that I can Edge Detect. I Warp them ever so slightly and then combine my two separate wireframes to get the overall pattern.
To get the frayed look of my wires, I had to start creating the concrete wall component early, so I left these as is to create holes. By subtracting where the holes in the wall would be, I could clamp them and create little spots where the wires would be able to punch through.
Wherever there would be a big hole in the wall, there’d be frayed edges. I’d Warp them slightly to cause them to bend and blend a Slope Blur version of the same wires with my hole mask to get them all beaten up and dented.
The biggest thing I found that made the wires so tricky was keeping the roundness of the shape and still maintaining that volume. It would be too spiky otherwise. I Blend a bit of random grunge overtop to help break it up, and to act as a lazy rust. The detail is so small it can be anything.
With a Height Blend, the wires are placed over. As we add more and more components, the values get pushed further away from white and more towards dark. The reason the components need to be so clamped is so I have as much range for the concrete section of the material as possible. The wall is very thick in my reference, so I would like to replicate that depth in the normal map while preserving cool details.
I make a quick lazy grunge for more rust which I then Blend on top of the wires using a mask from my previous Height Blend. This is just menial detail.
The final piece of the material is the wall material. You can see a few nodes going off to the bottom, this is mainly for the holes which used to punch out our wires from before. What is great about this setup is that if I change the random seed for my holes, it will adjust the wires as well. A well set up graph can give you many variations of the same material.
The first thing I do is copy my cracks and dents from my wood and play around with the values. I know that I’ll want some minor surface erosion, so I set them underneath my main chain for the wall so I can simply subtract them with a Blend when I get the wall shape figured out.
To get the shape of the holes, I use a Tile Sampler once again and just fiddle with the settings. I don’t care much for the settings themselves since I’m just going to Histogram Scan and then Slope Blur it over and over. One thing I’m conscious of however is to get some layering in this wall. An easy way to do that is simply to Blend two scanned masks together with different values. Now I have the White and Greys together.
Afterwards, I use a Blend set to Overlay to add some BnW Spots 2 to the wall. This adds a crumbly sort of feel. Using Overlay in a Blend node, it will only add the noise to greyscale values and not pure white or black.
Simply Invert Greyscale the nodes we’ve worked on so far and presto! We now have our wall, and with some different-sized holes as well. Depending on how I set my Height Blend, I can get some extra depth in the holes.
Finally, the last height information we need is to detail the surface. I use light Perlin Noise to add some very subtle shifts in height, and then use another one plugged into a Tile Sampler as a mask. I then set the settings of the sampler to be Thorn and then scatter them with my Perlin mask. This creates irregularities in the bumpiness of the surface. I run a noise and slope to add additional granular matter before combining them on top of my wall shape.
I then combine those cracks and dents I set aside earlier on top, using a blurred version of my hole mask to make sure they only appear in specific spots, usually around where the holes are formed.
And with all that, we have the final height map. See how much darker the wood planks and fabrics have gotten? This is because the Height Blend node in Substance Designer will automatically darken values to make sure the blend is using a full 0-1 range of greyscale. Since the concrete is the thickest part of the material, I needed it to have the most wiggle room in my greyscale range. Since each component was created individually, adjusting one will not harm the others, allowing for this procedural workflow.
With the completion of my height map, my normal map comes out as well, along with my AO. For this, however, I did use my hole mask and a second Ambient Occlusion node to lower the shadowing formed from the wires, as they were a bit too strong.
I could recycle this same mask for my metallic map, with just the wire height blend from when I blended it into my height.
The final steps are color and roughness, which are the most fun. I’ve seen some people say doing roughness first is easier than color and some say the other way around. It usually depends on what I’m feeling, but I like to block in colors with Uniform Color nodes before going further into either map.
The roughness for this graph was very simple. Since I had preserved several masks at various points in the graph and had the finished components already, I could simply use my individual components and various Levels nodes to adjust the roughness of each individual component however I chose. A well-constructed Height Map makes this part of the process a breeze. The other advantage of having each component separated is being able to lay various grunge masks over them as needed. This helps to break it up and make it seem not as homogenous.
The color map as you can tell has a very straight chain of nodes going from left to right to make up the final look. Again, recycling the masks I had been setting aside from the beginning of the graph (the ones I placed above everything else temporarily) and using my flood fill mask, I’m able to create places for my colors to go to. The wood receives a lot of the albedo love since being underneath the other elements of the material would grant them more dust and scratches.
I create an additional fiber pattern by using a Histogram Scan on the wood fibers I did before, just to create some sharpness to add white ridging to the rims. I also like to use a Normal + Curvature Smooth/Sobel to add some additional volume to the diffuse. Sometimes, I’ll use my Ambient Occlusion as a mask or even lay it on top just to add some extra depth.
At the end of the color chain, I use a Sharpen node to brighten my result a bit. It isn’t something I always do but for the render, I like having the extra definition in the albedo.
I usually like to take 2 renders, a fancy one and a flat shot. My flat shot just has a directional light and a skylight. My main worry with this project was that there would be lots of tearing in my height map, but thankfully I managed to avoid a very good amount of that. I’ve been considering splitting my material up and putting it together as a vertex blend set in Unreal, but that will have to wait.
Substance Designer continues to be such a fun software solution for me to express myself in. I think making off the wall materials (pardon the pun) and more abnormal stuff that may not be as practical has benefits. I learned a lot about managing proper height definition, as even without Tessellation, the wall still has its volume.
Doing personal projects like this is a good way to stay ahead of the curve and improve your personal skills. It can be hard to stay motivated sometimes when you work for a lot of the day, but it is always rewarding. I hope you all learned something from reading this breakdown!