PIPELINE TECHNIQUES: Perfect layering in Substance Designer
Eric Wiley’s guide to making beach debris material
In this tutorial we will be learning various methods of layering height maps in Substance Designer and the techniques I use for masking layers. While Substance Designer excels at natural materials it can be very challenging to create and layer complex man-made objects convincingly while also trying to keep any clipping and stretching to a minimum.
I will show how I created this beach debris material entirely in Substance Designer. I will cover shape creation, tile sampler layering and how I use flood fill and masks to create or avoid overlap. I will also dive into how I layer different types of objects and how I blend each layer. Although it is more time-consuming, combining more simple layers one by one is the best way to avoid the intersecting height map issue that might turn most people away from attempting a graph like this.
One of my main goals is to keep the placement as procedural as possible and only hand-place select graphs when we need to. Unlike most natural materials we will have many more types of objects and even some with multiple material types per object, because of this it will be especially important to keep our masks updated and organised throughout the layering process. This tutorial will primarily focus on building your height map and creating masks which you can then use to create your Albedo, Roughness, Metallic and Normal maps later on. For this tutorial I am assuming that you have an intermediate understanding of Substance Designer and are familiar with blending and the Tile Sampler node.
Create your object graphs Looking at reference, I chose about 30 pieces of debris to build for this material, each within its own sub graph. This will allow for more flexibility down the road if I want to go back and add details to a specific part. It also keeps our main graph cleaner. At this stage I am thinking about how the height maps relate to each other and also making sure I create a variety of types and sizes. I’m not going to go too deep into creating shapes here, but my favourite tools are the Shape, Transform, Curve and Bevel nodes.
Arrangement and scale Because we will be displacing a texture based on a height map, it’s important to arrange your objects in a way that won’t draw attention to the limitations of a displaced texture. As a basic rule I tend to have large, half-buried objects on the bottom and work my way up to smaller, thinner objects on top. At this stage I am deciding on the scale I want and thinking about how I want my final composition to look. Remember unlike natural forms, man-made objects have a specific size so we can’t rely on Scale Random to add variety.
Start at the bottom My workflow involves using Tile Sampler nodes to scatter my shapes and then blending them together layer by layer. Keep things simple by plugging in one type of object per tile sampler and spacing them out. I tend to keep my Amount and Position Random very low. This will keep objects within a tile sampler from clipping into each other and also allow us to use flood fill for different angles and values later on. For smaller shapes this level of control isn’t necessary, but with bigger objects where clipping will be obvious this is the best option.
Create overlap The most basic way to create overlap in Designer is to control the values of two layers and use a max (Lighten) blend or the height blend node. To achieve a more natural look you want objects to look like they are leaning on each other and slanted at various angles. This way you might get a wooden board that has one end above an object and the other end under another. The flood Fill to Gradient Node is perfect for this. You can either add or multiply this gradient to your objects depending on what you are going for. To make it even better, flood fill will randomise with every change so you can quickly find a look you like.
Masking and material ID each time I blend a layer with another I create a mask using the height Mask output from the height Blend node. Many objects will be partly obscured by the end and we will need these masks to differentiate our objects throughout our material. Because I have so many objects I decided to create a material id map with my masks as I went. This will allow me to use the Colour to Mask node later to make quick selections and I can also include small metallic details in this map from complex objects.
Think about value Since I’ve already used flood fill on many of my layers already, a great way to get more variety out of each layer is to use the Flood Fill to Random Grayscale node. On layers that we’ve been using the flood fill already this is especially easy to set up. Once I blend each layer’s random greyscale by each layer’s height Mask I should have a texture where every single object is a random value and masked correctly.
This plugged into a gradient map is a great starting point for our Albedo map later on.
Use the mask input For certain objects like intact bottles or cans you will want to imply that they are sunk in the sand and not clipping through the object below it. You can do this by adding together the masks of the existing layers and then inverting it and plugging it into the mask input of the Tile Sampler. Because of the randomness with tile samplers it’s a good idea to create an extra buffer in the mask just to make it even less likely that an object will appear where you don’t want. This can be achieved by using the edge Detect node on your mask.
Watch your heightmap As you work remember to constantly check your height map in the 3D view with tessellation. Your texture will always look best from above so be sure to look at it from multiple angles to check for bad clipping or stretching. The downside of man made objects is that you often have straight edges and harsh elevation changes. You can minimise stretching by slightly blurring your height map after the fact. If a blend is pushing your values to white, using a histogram Range node can get your height map back within a working value range.
A great way to get more variety out of each layer is to use the Flood Fill to Random Grayscale node
Layering flexible objects Say you have a flexible object like a rope or a cloth. Start by blurring your height map with a Blur hq Greyscale and blending (copy) that on top of the unblurred version. This blurred blend is masked by the silhouette of the object you are about to add. Your heightmap should now have blurred shapes in it. I then pipe that and the new layer into a blend (add) and adjust the value to what looks good. The intensity slider in the Blur hq node will make your objects appear more or less flexible while the object underneath maintains its form.
Finishing touches While the Tile Sampler node is extremely powerful and will get you most of the way there, don’t be afraid to add the occasional object by hand with the transformation 2D node. This is especially useful if there is an area of the texture that you want to add interest to. Rotation is best controlled outside the transformation 2D node as rotating this node can break tiling.
Making everything work together Once you’re happy with your height map you can make everything gel together by making the sand or dirt creep up the objects and gather in the crevices.
I really like using Dust node for this but you can also use the HBAO or Normal to height hq nodes. Combine this mask with your original sand layer mask to create sand that is collecting in all the cracks and corners.
Final render I chose to use Marmoset for my final render. I’d recommend ditching the perfectly flat plane and make one that has some height changes. This will create a much more natural look and give you more shadow to play with in your beauty shots. To help sell the depth of this scene I went pretty heavy on the ambient occlusion and cavity maps. To add even more interest I thought it would be cool to go back to Substance and make a water material to creep into the scene.
While the Tile Sampler node is powerful and will get you most of the way there, don’t be afraid to add the occasional object by hand with the transformation 2D node. This is especially useful if there is an area of the texture that you want to add interest to