Graph Layout Plugin - Part 2

Work In Progress / 26 October 2019

In the last part, I had managed to get this project to a point where it could handle simple graphs pretty well and was working on solving recursive chains that split and branch back into each other. I was finding it very tough!

I showed the plugin to my tech director and he gave me some really good feedback, mostly related to how to approach the problem and general programming guidelines. Simply put, I had made the code so unwieldy and difficult to use that I could not hold all of it in my head or even debug properly. He set me the challenge of limiting all my functions to ~15 lines of code and with only 2-3 inputs; It really helped, thanks Christian!

So, I've rewritten the whole thing from scratch...

After spending some time trying to use it properly, I found the assumption of organizing an entire chain based on a single selected root node incredibly destructive. A lot of the time, I only wanted to quickly layout a small portion of the graph and leave other parts intact. So that's the first thing I fixed, it now works on your selection. I also hated clicking an icon, so it's now hot-keyed and supports a proper single undo. Previously it would undo one node at a time, ugh

This made working across multiple chains easy to implement, and can now handle multiple root nodes. In addition to this, placement now tries to find the longest horizontal in an attempt to produce the clearest results.

This means you can selectively manipulate node placement if you want too!

The biggest change however was with branching nodes (multiple inputs) and split nodes (multiple outputs). Previously I was recursively solving from the root (right to left), solving each branch as I got to it. Now however, I solve from the end to the chain up (left to right) and in an ordered fashion, which actually removed the need for recursion entirely and made node placement way easier.

So now chains originating from a split node are much more robust.

Its still being done in two passes like before, but now I only need to keep track of which split nodes have already been considered and if they need to be updated due to an offset.

Everything in the images so far are actually only solving along the x axis, I haven't got around to re-implementing the y offset yet, so that will be the next step. But I'm feeling happier with the development and think the algorithm is working much better now. The results in the gif below might look messy still (since its missing the y offset) but the x axis is solving correctly even for fairly complicated networks.

Thanks for reading!

Graph Layout Plugin - Part 1

General / 26 September 2019

In typical fashion, instead of finishing anything, I start something new. A plugin to organize Designer graphs!

This has proven to be a very interesting and challenging problem. A lot harder than I initially thought, but I have managed to reach a point where I can reliably sort a simple non recursive chain into my preferred layout style. 

The current implementation involves traversing down the chain building a coordinate system, then going through the chain again actually placing them according to the coordinates. The goal was to build these lane structures that respect the dimension of other parts of the network, so when finding a branch node (such as a blend), I step down each branch and return with its dimensions. This doesnt sound too bad, except how much to offset the nodes up and down also depends on which input slot the entire chain belongs in to begin with! It took some late nights and what was left of my balding hair, but I have a working solution now!

Networks that feed back into itself are a whole other beast, but I have made some progress here. There is a concept of a queue, where a split node (node with multiple outputs) will only position itself if all of its parents positions are known. If it cant successfully position itself, then it gets placed back into the queue, otherwise the whole process above repeats, building a brand new chain network. Theres are issues with this that I still need to work through, but its working well enough to show at least. So if there are any wizards reading this, tell me the magic! 

None the less, it has been a great exercise for me and I am learning a lot. In fact, the biggest challenge so far has been trying to work out exactly how I want the layout to behave and what that rule set is mathematically! Perhaps I can be a little better at blogging my process going forward too!

Thanks for reading!

Lets Talk Color Pickers - Part 2

General / 02 June 2019

Hey folks!

In my last blog post about color pickers, I was exploring a way to procedurally generate color charts based on an input color and exposing different variation sliders. Since then I got the chance to work on a Substance Source Signature Series which meant I got extensive time working with the node and I discovered some things I was not happy with.  Some revisions were made for the Source release, but these mainly related to removing the dependency on a px processor in order to work with the CPU engine better. What you see in that series is more of less the node I detailed in the previous blog, but CPU friendly. I do go through the inner workings of it during a live stream, so if your interested check that out or you can grab it directly from the .sbs files if you have a substance source subscription.

Now however, I am doing another pass on the node. Giving it a big tidy up, making it more robust and reverting back to px processor based (A CPU friendly version is now on a switch, instead). Value and hue variance is done in two passes as before, except its now packaged with the node and inputs exposed. Additionally, there is a mask input to provide a way to blend back the input color, which is very helpful in making sure you don't stray from the original intention. I found I rarely used the saturation variation, so that's gone. Along with the seed offset sliders for each channel. In practice just having a single seed was more than enough and was barely used anyway.

The main problem I had was mostly to do with how I was generating samples. I was using the same value for both generating sample points with a tile generator and to dynamically control the output size of the color chart. This meant the sample counts grew exponentially and very quickly became noisy or nonsense data. So my first step was to fix this and generate a sensible number of samples points. This is now done with a 16x16 fx map so its super fast and much more understandable.

This did pose a new problem though, as when these samples upscale to full res, they were not interpolating correctly. So I also do my own linear interpolation during the upscale to ensure I get precise gradients between each value. Below are the sample points being linearly interpolated correctly.

Hopefully now the sample count is more understandable and intuitive. (Sorry for the .gif compression)

I was also unhappy with how the hue blending worked with low saturation colors. Previously I was forcing the Saturation to 1 with a HSL node in order to blend it back on top of the original color. While this does produce nice results, it had a weird side effect of brightening the overall values. Instead, I now convert to HSV, so when adding hue variance it will not affect the brightness. This is the default behavior for the node and means it will respect the original saturation correctly.

Of course, the hue variance slider remains. That is, how much to blend in the variation. And also the value variation and hue range sliders; How much to offset the value and hue respectfully. Except now that it is px processor based again, the hue offset is truly random, rather than a blend between two extremes.

As before, you can choose to blend the hue back on top instead of preserving Saturation, which now feels nicer with the HSV and sample changes. As you expect, some colors are better suited for this than others.

I also found soft light in particular has nice results, so that's available as well.

The graph independent seed also remains, which with the high hue values, allows for some really interesting colors!

Thanks for reading!

Optimize Graph Plugin

General / 04 May 2019

Hey folks,

I have recently been exploring Designer's Plugin API and working on a tool to automate some graph optimizations!

So far, the plugin is doing 3 main optimizations, the first of which is detecting, deleting and reconnecting any duplicate generators you have. Nodes like noises or tile samplers for example. It will also recognizes if you have any exposed parameters on the node and make sure not to delete those!

Next up uniform color nodes. The plugin will force the node to 16x16 (the optimal size for the Substance Engine) and set all connected nodes back to relative to parent, unless the given node already had manual edits to its output size

Finally, it will set a blend nodes' Alpha Blending mode to ignore alpha if it detects both inputs as grayscale.

The goal being to simply select an entire graph and let the plugin do its thing.

If you have any other ideas of what could be automated, let me know!

Substance Manager Tool - Part 2

General / 19 April 2019

Hey all,

I have been fairly busy recently so took a bit of a break from the Manager tool, but I now have a new update! 

I got myself setup with my own Perforce server so I can properly backup content and use version control, bringing me closer to how I am used to working in a studio. Following this, I wanted to learn a bit of PyQT ( a more robust GUI library for Python if you have not heard of it ),  so actually took a step back from the main app to develop some new things.

One of the issues I now have as my library grows and I do more projects is all the junk flooding designer. For example, if I search for a ground, I get wip files, renders, psd files, exported textures you name it.

This is because I had basically set up designer to point to some root path and recursively search everything inside there. And after my last foray into shuffling files around, I have all source files nested with the parent graph.

Thats pretty messy, so instead I wanted to path designer to specific directories and not do a recursive search. Thing is, that could be a lot of paths.

So I developed a project app, that will create a .sbsprj file with my perforce details and given a root directory, automatically locate child paths for designer to watch, with dark skin too ;)

It does this by looking for a shelf.ini file, which I place in each directory I want designer to read. If I want to add a new path or project, I simply add this file and re-save from within the tool.

So I created a project for all my personal work and set their related watched paths.

Since I don't always need content from older projects, I wrote a supplementary app to manage the installing of the projects.

This tool will write a config file with the projects selected and then tell designer to use that config file. Now everything is really easy to manage and the shelf is super clean!

At least for now.


General / 04 April 2019

Hey all!

Alex Beddows was silly enough to invite me for a podcast. We have a nice chat about all things game development. I wonder if he regrets it now? 

Stone Layering Series 50% off!

General / 01 January 2019

2019 is upon us and it has been incredible seeing the community grow over the last year, so lets continue improving and kick things off with a 50% discount! Make sure to use the discount code newyearsubstance or the links below!

Happy new year everyone!

Lets talk color pickers in Substance Designer!

General / 11 November 2018

A common problem I seem to have when building an albedo texture is finding the balance between material flexibility, user friendliness and uniqueness. 

I like using uniform color pickers instead of HSL nodes because I find visually choosing your color is more intuitive. It also means you can set up the color pickers in such a way that your albedo can have a primary, second and tertiary colors. The problem is, its very hard to get a good variety of colors when only using uniform colors.

The gradient node does a good job of solving the variety problem by letting you sample many colors at once from reference, but then you loose the color picker flexibily and it becomes very unstable if using the gradient dynamic node or building color variations. How many hours have you spent getting your colors to look good, only for it to fall apart when you change the random seed value of the graph or the overall color of the material. If your anything like me, a lot.

These problems are what iv tried to solve with this node. Lots of videos below, so keep scrolling!

At its core, it's a simple color picker with HSL variation sliders:

Whats neat is the HSL channels are totally independent from each other.

You can also adjust the number of samples that should be taken too

When you start to layer these up, you can get some nice variety of colors. Its still controlled by a simple color picker though, giving good reliable control over the material. In this example, there are two layers.

And the built in seed value will sample different colors.

The important feature here, is the node is totally independent from the graphs global random seed value. Meaning what ever colors you set, will remain consistent regardless of the input.


This decoupling from the random seed value is really powerful when you plug in a color chart to the color input slot. Here I sample some colors from a reference image and use that information to sample colors from instead.

Notice its still preserving color when changing the random seed and instead we use the internal seed value to sample different colors from the chart. As before, we can choose how many samples we should take too.

We still have access to the variation slider too!

That is as far as iv gotten for now, so let me know your thoughts!

4C: Prague Conference - See you there!

General / 21 September 2018

I am pleased to announce that I will be speaking about Environment Texturing in Wolfenstein 2 at this years 4C conference! Its a relatively new event hosted by Wargaming and this time its coming to Prague!

There is gonna be some really nice talks this year and starts on the 5th Oct

If your going to the event, be sure to swing by! Otherwise, I think you will be able to listen to me babble later online.

Substance Manager Tool - Progress

General / 01 September 2018

Over time my library of substance nodes and folder structure has grown into a mess. So iv been building a tool around the Automation Toolkit to manage this and organize everything from one place. For those who are unfamiliar with it, the Automation Toolkit is a set of Python tools from Allegorithmic to manipulate substance files, and well, its pretty awesome.

My tool is still heavily wip and missing many features but here is my progress so far. On the left, it reads a project directory, listing all sbs and sbsar files in that directory. And then on the right, you can read and view the content of a file, displaying all the graphs, attributes, resources and dependencies

 I messed up the recordings a little and don't have a mouse cursor, but you get the idea.

The tool also lets me move any substance files from one location to another, bringing along any source data it finds with it as well as searching the entire project and updating any files which might have used the moved substance.

How does it know what source data to look for? Well at the start of this, most of my substance files were in folders like this.

I got all sorts of junk here, all in one folder, what a mess. So I wrote a converter to take all this stuff and organize it neatly, with _source folder for every substance. Thats what the tool looks for when moving files

The tool also allows for relocating of resources and dependencies. You can either manually search for the path, or have the tool try to automatically find the missing dependencies for you. If it finds more than one potential match, it will ask you to choose one.

You can also search through the entire project to find out where and which files are using a given substance

Hope you all like it so far!