Texture scope change

My biggest problem with the otherwise great Substance Source Material Library is that the scope of the textures, the area they cover is very small, usually in 1×1 to 2×2 meters. There is no support in Substance to increase the scope of materials so if I wanted to avoid excessive tiling on even moderately scaled surfaces then I pretty much had to redo the material from scratch. The issue also crops up with photogrammetry where sometimes a wider shot of a surface is impossible to obtain.

Texture scope change TextureScope4 300x300


Texture scope change TextureScope5 300x300


Fortunately with the advent of machine learning there is now possible to work around the problem: Enter Artomatix ArtEngine!


“ArtEngine hosts a set of features aimed specifically at increasing the users ability to exercise their texture vision, while also reducing the time needed to achieve it.”

In order to use ArtEngine to change the scope of a material first we have to prepare a texture atlas of all the pieces we have. With Substance this means randomizing and saving a texture set several times, creating typically 2×2, 3×3 or 4×4 tiles. (In this article I’ll only show the base color textures but ArtEngine processes all the textures in a PBR set so they remain matched.)


There are a few ways to do that:

Texture scope change TextureScope2 300x167

The atlas can be built in any 2D image editing application by snapping the images (saved from Substance Player) to each other in a properly sized canvas. This is fairly quick to do if we only need color but gets increasingly tedious with additional channels.

Texture scope change TextureScope1 143x300

Alternatively in Substance Designer we can link up several instances (with different seeds) to Bruno Alfonseca’s Atlaser node , creating the atlas. Linking up the channels is somewhat tedious and depending on the used materials it can also get time and memory consuming to render the outputs.

Texture scope change TextureScope3 300x216

Something similar can be done right in ArtEngine too. There the material channels are handled as a single unit which is nice but setting up the Free Transform nodes is a fair amount of donkey-work.

And finally we can use ImageMagick, a command line tool to assemble the image. Its Montage feature is exactly what we need. For example the following command


magick montage wood_red_cedar_Base_Color* -geometry +0+0 wood_red_cedar_Base_ColorA.png


would create an atlas (called “wood_red_cedar_Base_ColorA.png”) from files called “wood_red_cedar_Base_Color1”, “wood_red_cedar_Base_Color2” and so on.

Writing this command is not super comfortable but much faster than any other method when it comes to many files like full PBR channel sets in a 4×4 grid.

With the atlas done we can import the texture to ArtEngine and turn them into a material. The exact node graph processing it depends on the contents of the texture so let’s see a few typical use cases.

Texture scope change TextureScope8 300x180

This is the simplest graph: the 3×3 atlas of the torn cardboard texture and a black and white image is fed to the mutation node. The latter picture is the “ignore mask” where the black lines, covering the seams between the atlas cells, mark the areas which should be, well, ignored by the algorithm.

Texture scope change TextureScope9 300x300

The 3×3 atlas was stitched from 512×512 images exported from Substance Player, producing a 1536×1536 texture.

Texture scope change TextureScope7 300x300

The result is a 2048×2048 image (ArtEngine only deals with power-of-two resolutions) but the feature size remains the same as on the input texture. I left the Mutation node’s settings on default.

Texture scope change TextureScope11 300x276

In the case of this crooked medieval roof I used a 3rd input image, a structure guide to give ArtEngine a rough idea what pixels belong together.

Texture scope change TextureScope12 300x300

I didn’t spend a lot of time on this, simply applied an edge detection filter on the heightmap, but it turned out to be good enough.

Texture scope change TextureScope50
Texture scope change TextureScope10 300x300

I zeroed out all the variation parameters of the Mutation node so it only replaced the seams (filled the black areas on the ignore mask). The result is not perfect but fairly good. With a better structure image and wider black lines in the ignore mask things would probably look even better.

Texture scope change TextureScope14 300x300

For this medieval wall I did build a proper structure image which improved the result considerably.

Texture scope change TextureScope15 300x300

I toned down the vertical variation of features so the brick layers are maintained.

Texture scope change TextureScope17 300x300

Now let’s take a bit more complicated graph. We start with for variations of this flowery grass texture.

Texture scope change TextureScope16 300x215

This first part of the graph assembles them into an atlas.

Texture scope change TextureScope20 298x300
Texture scope change TextureScope18 300x149

Then we create an ignore mask to be used later. With a color selection node the flowers are marked black then a noise texture randomly whitens some of them. The usual black seam covering cross is blended in at the end.

Texture scope change TextureScope23 300x300

Next two mutations are created: one using the usual ignore mask, one with the most flowers ignored. The former creates a field with a uniform density of flowers which doesn’t look organic. And that’s where the second mutation, with sparser flower coverage comes in: using a noise texture we blend between the two to create a more natural result.

Texture scope change TextureScope29 300x300

Adding large scale details is also necessary when dealing with rock surfaces. Once again we start with a 2×2 atlas and increase the scope.

Texture scope change TextureScope24 298x300

It looks good on the small scale but from afar the homogeneity is rather unrealistic.

Texture scope change TextureScope25 298x300

Let’s do another, low-res mutation, scale it up with the Up-Res node (almost the equivalent of the “enhance” button in movies)…

Texture scope change TextureScope26 300x300

…and blend it over the other image.

Texture scope change TextureScope30 300x300

It is also possible to mix quite different textures for a more varied result.

Texture scope change TextureScope27 300x300

The patches might end up looking very different from each other but the Color Match node can take care of that.

Texture scope change TextureScope28 300x297

Unfortunately changing the scope of wood textures remains a challenge. It makes a valiant effort of fixing the seams but it’s still a mess. However there are a lot of possibilities in ArtEngine so I’m not yet convinced it can’t be done with it. I’ll experiment more.