Daniel Swing did a breakdown of his procedural Key Ring Generator made in Substance Designer and explained the logic behind the nodes used.
Hi, my name is Daniel Swing. I’m currently a 2nd year 3D graphics student at FutureGames in Stockholm, Sweden, and I’m about to throw myself into the games industry and start a career. I’m here to talk about my ‘Key Ring Generator’ that I made in Substance Designer a few weeks ago.
Substance Designer Advantages
I’ve been using Substance Designer for a little more than two years. I got started in February 2017 for the bi-weekly Substance Challenge at Polycount. That’s where I initially discovered the depth of Substance Designer and the possibilities within the software.
Back then, what really stood out to me about Substance Designer was that I could get visual results very quickly.
I was used to the “regular” workflow of modeling/sculpting -> retoping -> UV-mapping -> baking -> texturing, jumping back and forth between several different software solutions (all of them with their own little quirks) – this is fine but a bit time-consuming for certain assets.
In Substance Designer, I could achieve somewhat pleasing results within just a few minutes, much faster than I would with my “regular” workflow. And that’s what kept me using Substance Designer and learning the software.
Today, what I love about Substance Designer is that the workflow is procedural, modular and non-destructive (something I’m really missing in other software workflows).
Example: Instead of manually sculpting 100 different rocks (while keeping a united shape language between them all), I can set up a few basic rock shapes in Substance Designer, deform and warp them with different patterns and blend in some noises to get infinite variations of rocks. I can create variants by just changing the random seed, instead of having to remake the entire asset from scratch.
And I never have to commit to anything. I can change anything and everything at any time, making an iterative workflow extremely easy. If I realize that the rocks are too big and I need to make them smaller, I can just go back in the graph and change a few numbers/parameters, and the rest of the graph will update accordingly. If I want to make the rocks’ surface less noisy, I can just reduce the noise influence on all rocks at the same time. If I want to introduce a new type of damage, wear or cracks in the rocks, I can add it any time to my graph – I don’t have to follow a strict plan from start to finish.
In the “regular” workflow that I described before, making these changes half-way through the process would essentially mean to start from scratch and move back to the ‘modeling/sculpting’ phase. But in Substance Designer, iteration is just part of the workflow.
The Key Ring Generator
This procedural, modular and non-destructive nature of Substance Designer brings me to the topic at hand, the ‘Key Ring Generator’.
A somewhat common situation in games is “You got a key!” and a close-up shot of a key appears on the screen, or a thumbnail of a key in the corner saying “added to your inventory”, or something similar. Unless your game has a universal “Small Key” to open every lock, you probably want to have some variety. But how many variants? It may not be feasible, time-wise, to make a large number of variants for such a small, tiny and trivial object.
Unless you approach it in a modular and procedural way!
My goal was to make a modular and procedural key generator that could be used by an artist to generate several different variants of keys.
As I mentioned before, the workflow in Substance Designer is very iteration friendly. When I started, I didn’t know exactly how to tackle this or how the end product would function or what it would look like – I had to test a few different variants before I settled for a method.
At first, I was thinking that the entire key should be generated in one node (key head, key shaft, and all PBR channels all in one) but I realized that by separating them out into different nodes, I could keep them much more modular and less cluttered.
Let’s start dissecting the “Key Cutter” node:
As you can see, there are a lot more nodes to handle the ‘Key Head’ than it is for the ‘Key Shaft’. This is only because I wanted to make several different pre-made head shapes. A lot of manual work had to be done for the ‘Key Head’ portion (for example, the positioning of the text needs to vary depending on what pre-made head shape is selected), while the ‘Key Shaft’ section of the graph instead contains a lot more complex, procedural function graphs.
Some of the pre-made head shapes are just very simple geometry while others needed more complex masking techniques.
After compiling 19 different pre-made shapes (+ a custom shape input), I funnel them into a multi-switch (which is connected to the variable that allows the artist to choose what pre-made head shape they want to use) and then I process the head shape with all the common parameters they all share, like controlling hole shape and size, border thickness and falloff, pattern overlay, text blending, etc.
The ‘Key Shaft’ section didn’t need as much case-by-case control and is therefore much more fluid.
Here you can see how I start with a uniform, black color, turn it into white squares and rectangles by using the ‘Cropping Area’ parameters in the blend-nodes, and later cut teeth and rivets into it. The real trick here was to expose the right parameters to allow an artist to customize the key’s shaft. Example: The ‘Teeth Depth’ variable controls the intensity of the second directional warp in the graph, while ‘Teeth Depth Randomness’ controls the ‘Color Random’ parameter in the tile sampler (the one with the horizontal gradients).
When I work in Substance Designer, I always start with the height information (the ‘Key Cutter’ node, in this example) and use the heightmap as a base to generate all the other necessary PBR channels. The ‘Key Ring Generator’ isn’t an exception, the only difference really is that the ‘Key Color’ node only has access to the final height output from the ‘Key Cutter’ nodes (I can’t reuse much else information I generated in the heightmap process like I normally do). This posed some problems that I had to find solutions for.
The ‘Key Color’ node takes ‘Key Cutter’ nodes as inputs. From the given height information, the ‘Key Color’ node generates a few generalized masks (0.5 linear is “middle”, any height value below that is masked out and treated as “engraved”, any height value above that is masked out and treated as “protruding”). I mix and match these different masks and blended them with some noises (essentially, mask generators similar to the ones you can find in Substance Painter) to get some more specific selections (to mask out metallic and non-metallic parts, etc.) – these masks are procedural and will stay consistent. No matter what key shapes I input, they won’t need any manual adjustment.
Again, all of this is something I didn’t know I had to do at the beginning of the project and it’s also something I didn’t get right at first try. These mask generators needed a lot of testing, revisits, and slight adjustments before they became generalized enough.
It’s with these generalized masks, the heightmap (to generate Curvature and AO information) and a few procedural noises that I created all the necessary PBR channels (Base color, Roughness, Metallic, etc.).
I used my own ‘Multi-Directional Warp’ node (functions very much like the one that came in a recent Substance Designer update) and used the height and curvature information to warp noises to the shape of the keys (the warping is 100% dependant on the key shape that gets inputted) and blended these different patterns and noises using the procedural masks.
When it comes to customizing the material, most parameters in the ‘Key Color’ node are just exposed ‘Intensity’ values in blend nodes.
Here you can read about how I tackled the specific problem about resizing the keys’ head, and how I went about to find a solution (an example of how I identify an issue within my own graph and how I solved it).
What Can This Be Used for?
This ‘Key Ring Generator’ only produces textures and no actual polygonal geometry (and personally, I find them lackluster to look at when rendered on flat planes).
Highly tessellated and displaced planes aren’t ideal to run in real-time, as it takes quite some performance. But that doesn’t mean this ‘Key Ring Generator’ can’t be used to create assets and content for games or other visual, real-time media. The heightmap can be used to generate high-poly models in software such as ZBrush or Maya, for example. The transparency/opacity mask could also be used as a guide for Quad-Draw tools to create low-poly models. And sometimes, a full 3D model is not even necessary.
Other similar, procedural tools could be used to create procedural screws, nuts and bolts or other decals (both organic and hard-surface), to be used as heightmaps in ZBrush or tools in Substance Painter.