Tilesafe Rotation in Substance Designer

Tutorial / 05 January 2022

The Problem

When you are working with Substance Designer one of the main goals is to keep your material and textures tileable. Designer offers a lot of tools which keep your tiling intact. But when you rotate a noise or Grunge-Map, you will run into problems. 

Designer provides a node which helps you with that as well, it's called Safe Transform, with that node you can easily rotate the input and keep it tiling.

It works great with angles like 0°, 45°, 90°, 135°, 180°, 225°, 270°, 315°, 360°

What if you want to rotate your input by lets say 26.5651°?It will break the tiling.


The Goal

In this tutorial I'll show you a way to rotate the input by a much larger number of angles and keep the tiling of the texture.


The Method

The method we are using is quite simple and follows these 4 Steps

  • Take the unrotated texture and tile it horizontally and vertically multiple times
  • Rotate the tiled image
  • Find the smallest repeatable piece of the rotated image (This is where a little math comes into play)
  • Crop the image into the size of the tileable piece

The Math

Like I already threatened you there is a little math involved here, but don't be afraid, it's very simple geometry. At the end of this section you'll get an easy to use collection of formulas ;-)


Step 1 - Take the unrotated texture and tile it horizontally and vertically multiple times (here the tiling is 7)

Step 2 - Rotate the tiled image (in this case by 26.5651°)

Step 3 - Find the smallest repeatable piece of the rotated image. We calculate h_h, h_w, w_h, w_w with the formulas provided at the end of the section.

We can simplify it a little, since we are working with a square texture we just need to calculate h_h, w_h. When we are done with these calculations we find the reduced fractions that correspond to (h_h / h_w) and (w_h / w_w). 

Be careful, if these are not rational, you won't be able to find reduced fractions which make sense, so you will not be able to find a width and height which is tileable.

Here we have to use a little trick, the tangens of the rotation angle should be rational, to achieve this we use a rational fraction to derive the rotation angle. So basically we choose a integer ratio between h_h and w_h before we do all the calculations.

Here are some examples:

Angle        tan
5.71059°     1/10
11.3099°     1/5
14.0362°     1/4
18.4349°     1/3
26.5651°     1/2
33.6901°     2/3
45.0000°     1/1
56.3099°     3/2
63.4349°     2/1
71.5651°     3/1
75.9638°     4/1
84.2894°    10/1

I made a Spreadsheed with a lot of angles with rational fractions, to help you with this. Just open this Google Doc

Step 4: Crop the image into the size of the tileable piece


Formulas

Now you have everything you need to create a rotated tileable texture in Substance Designer but Substance Desinger provides us with the Pixelprocessor, so we are able to create a elegant node, which does this whole math, rotating, cropping, tiling for us.


The Implementation

Here is the full graph inside the Pixelprocessor, I will explain the different sections step by step

First we choose an angle, where the result of the tangens is a "nice" rational fraction, convert this into a Float2 and use the ArcTangent2 - Function to get the angle in radians.

Next we calculate h' and w' which is the scalefactor for the texture at that angle, for this we multiply h_w and w_w by the reduced fraction of our input angle.

Then we calculate the rotation at this angle and multiply the result by the scale-factor from the previous step.

This gives us the correct scaling and rotation of the texture, so we use this Float2 as sampling position.

I hope you enjoyed this short tutorial on how to tilesafe rotate a texture in Substance Designer. If you want to look into the .sbs or just use this tool, you can download the finished node from my from a google drive here.

Stay healthy and creative

Marco

Water Ripples in Substance Designer

Tutorial / 11 January 2021

A water ripple is basically just a some kind of radial wave-function moving away from the center, while loosing energy (height). But is it really that simple? Let's take a closer look at a Reference Photo. 

It seems, that at the ripple has one big wave in the center and while moving away from that point, it looses energy (height) and gains frequency. I read a little bit about the special behaviour of water and surface tension and got a lot of articles discribing, how a ripple forms. What is the difference between a ripple and a wave? At the end of the day I had all the math and physics for building a water ripple.

I experimented with some exponential increase of the frequency and at the same time, some other exponential decrease of the amplitude all applied to a sine function. I searched for some constants and stumbled over a YouTube-Video and more important a link to an over 20 years old coding-website, which only exists in the webarchive (2D Water) by Hugo Elias who found that algorithm somewhere else.

The algorithm he discribed was so elegant and simple to implement in designer that I just tried it and the result was fantastic. Let's take a look at my implementation in Designer and see how the algorithm works.

The Main-Graph (water_ripples_buffer.sbs)

The Main Graph is basically just a Pixel Processor with three Input- and Output-Nodes. The important thing is, that the Pixelprocessor - Output is connected to Buffer 1 - Output and Buffer 1 - Input is connectded to Buffer 2 - Output.
The rest of the magic happens inside the Pixel Processor.

This is the whole Pixel Processor Graph, separated into three sections, Output-Conditions (green), Neighbour-Values (red) and the sum (blue).

First we have a look at the Output-Conditions.

These three conditions, influence the behaviour at the image-boundaries or the custom-mask. The left condition is only true for non-edge-pixels, so the reflection at the boundaries happens. The next condition is true as long as the custom-mask input has a value below 1, that creates the iteraction with the mask and the reflection-effect at the edges. The last condition takes care of the case, where the ripples just seamlessly tile at the edges.

The next section, we'll have a closer look at, is the Neighbour-Values (red) 

These four frames take care of the main-part of the algorithm

FOR EVERY PIXEL IN THE INPUT BUFFER 1:
  ADD UP ALL VALUES OF ITS DIRECT NEIGHBOURS (LEFT, RIGHT, TOP, RIGHT)

After adding up all these values, we take a look at the final step

- DIVIDE THE SUM OF ALL THE NEIGHBOUR-VALUES BY 4 (AVERAGING THE VALUES)
- SUBTRACT THE INPUT BUFFER 2 (SUBTRACT THE PREVIOUS STATE)
- MULTIPLY BY SOME VALUE LOWER THAN 1 (ABSORBTION)
- CHECK THE OUTPUT-CONDITIONS
- OUTPUT THE RESULT

And this is what happens, when there is some kind of collision-object (custom mask)

This is the result rendered in blender cycles @ 512 Samples


Thank you for reading and don't forget to download the free generator from my store

stay safe and all the best Marco

MyTips #2 - String to Pattern

Tutorial / 14 December 2020

Inspired by Martin Schmitters (www.artstation.com/martinschmitter) QuickTips, I began to do some of my own.

Here another one on how to create complex patterns with just a Text-Node.

I hope you like it and I'll make some more in the future. Feedback very welcome.

All the best Marco

MyTips #1 - Welding

Tutorial / 03 December 2020

Inspired by Martin Schmitters (www.artstation.com/martinschmitter) QuickTips, I began to do some of my own.

Here is my first Tip on how to create welding in Substance Designer.

I hope you like it and I'll make some more in the future. Feedback very welcome.

All the best Marco