Jump to content
You must now use your email address to sign in [click for more info] ×

Affinity Photo Procedural Textures for Absolute Beginners: 101.5

Recommended Posts


(Part 1 is HERE.)

In the tutorial we are going to look at a more complex example of using brackets to expand the usefulness of Procedural Textures.

Using the techniques we’ve learned so far, we’ll produce a beautiful and adjustable watercolour background texture like this:



First, create a new document with a filled pixel layer and add a Procedural Texture. I you are unsure how to do this, look at the beginning of the previous tutorial.

Select the Simple Perlin Noise preset.

To create the watercolour background texture I showed you at the beginning of this tutorial, I started with the basic Simple Perlin Noise preset equation - perlinsc(rx/200,ry/200,7,0.6)*0.7.

At face value, it doesn’t seem to bear any relation to perlincubic((rx+500)/((w*2)/b),(ry+500)/((h*2)/c),7,a), which was my kicking-off point for making the texture, but let’s break it down:

Important note: This equation is going to be used for the red channel only. We’ll need to two more for the green and blue channels. Don’t add them now. I’ll take you through the assembly of the texture later.

Instead of making perlinsc I thought I’d experiment with another Perlin noise function – I picked perlincubic (there is a full list of Perlin noise types in the help file under Procedural Texture).

The whole set of instructions for making perlincubic noise are contained (must be contained) within an opening and closing set of brackets:


NOTE: There’s no brightness control at the end outside the closing bracket – I ditched it for the sake of simplicity.

Looking back at the perlinsc equation, it has FOUR parts, each separated by commas.


It’s the same here:


The four sections are:

SECTION 1 - ((rx+500)/((w*2)/b)

This segment is the instruction for how to make noise across the image. It is has got three parts (rx+500), (w*2), and b. Each part is separated by a / (divide) symbol. rx we know from the earlier tutorials is an instruction to make click-draggable noise across the screen starting in the top left corner. +500 is a way of telling Affinity to make the starting point for the texture 500 pixels in. This is must be enclosed in brackets so that Affinity knows to read this as a single instruction.

It is now going to DIVIDE that by the next part (w*2).

w is C++ code for the width (I think) of your document, which in this instance is to be multiplied by 2.

In order to just multiply the width by 2 and nothing else, the w*2 must also be put in brackets – (w*2). Using the width of the document to determine how the texture is made appears in some of the default equations like Urban Camoflage. Purely by experimentation with other equations I discovered that dividing rx and ry by the width and height is a good way offsetting the texture at the same time as scaling them.

The b segment of this section is a custom input. Affinity looks at all the stuff in front of the b and then divides it by whatever number is put in the b Custom Input controller.

Look, as a texture tweaker, it’s not essential to understand the maths, just what the equation is doing. It’s taking all sections enclosed by brackets as separate parts to be dealt with individually. So long as you keep the stuff inside the brackets you can tweak and experiment to see what happens. Numbers inside brackets can be swapped for Custom Inputs and vice-versa, multiplication signs can be swapped for division signs etc.

Just remember the brackets golden rule – What happens in brackets stay in brackets.


(ry+500)/((h*2)/c) Is the next section of the equation does exactly the same, but instructs Affinity to make the noise going down the image. h is C++ code for the height of the document and c is another Custom Input.

SECTION 3 - 7 This section is an instruction to set the amount of detail or noisiness (officially called Octaves).

SECTION 4 - a This segment controls the smoothness of the detail (officially called Persistence).


Creating the Texture

Open the Procedural Texture dialogue box, if you haven’t already opened it (Filters>Colours>Procedural Texture).

If there are any equations in the top section, delete them clicking the X at the end of each line.

Likewise, if there are any custom inputs in the bottom section, delete those in the same way.

Click the + sign at the bottom of the Equations section three times to add three empty equations lines. Each should have the R, G, & B, highlighted in turn.


Add 6 Z custom input number controllers and one -1,1 custom input sliding controller.


Copy and paste this equation into the Red channel equation box:


To make the equations a little easier to make sense of, change the b to rw (for Red Width); change the c for rh (Red Height); and change the a at the end of the equation to sm (smoothnes). The only reason for doing this is for ease of working - sm doesn't do anything, you could just as easily type banana. Stick with sm for now so that the equation now reads:



Nothing will happen until we assign the custom controllers with the same values.

First, we’ll set the smoothness, that way we’ll see the texture develop as we edit the other controls.

Change the letter g in the -1,1 input to sm, name it Smoothness, and set the slider to about 25%.


Change the first Z input value (a) to rw. Give it the name, Red Width. Give it a starting value of -9.

Change the second Z input value (b) to rh. Give it the name, Red Height. Give it a starting value of 2.


opy the equation from the Red channel equation line and paste it into the Green channel equation line.

This time change rw, and rh to gw and gh.


Change the next two Z custom inputs to match the changes, creating controls for Green Width and Green Height. Set the width amount to 12 and the height to 2.


Copy the equation a third time, pasting it into the Blue channel equation line.

Change the equation again to be bw & bh.


Change the last two Z controllers (e & f) to bw & bh, naming them Blue Width and Blue Height.

Set the Blue Width amount to 16 and the Blue Height amount to 3.


The final texture dialogue should look like this:



Save this preset as Watercolour Background.

If you find at any stage you’ve got a blank document, you may have a mismatch between the value names in the equation and value names in the controls. I find it’s very easy to change rw (red width) to rg instead of gw, for instance.


You’re probably wondering why I used a -1,1 slider instead of a 0,1 slider. The main reason is that you can get different pattern variation either side of the mid (0) point.



Don’t forget this is click-draggable!


Colourful Clouds

Red Width = 3

Red Height = 2

Green Width = 4

Green Height = 3

Blue Width = 7

Blue Height = 5

Slider 20%

Horizontal Rainbow Bands

Red Width = 3

Red Height = 151

Green Width = 5

Green Height = 157

Blue Width = 7

Blue Height = 159

Slider 30%

This Last one looks great on text:


FINAL TIP: Texture not working? Count your brackets and keep your commas! When you have an equation with lots of nested sets of brackets (e.g. (((a*b)*(c*d))*2), it’s easy to miss adding an opening or closing bracket. If you end up with no texture, count the number of opening brackets (, and then count the number of closing brackets ). They have to be the same. If they aren’t, you’ve missed one or added an extra one. Finding the error can be tricky. First look to see if the individual parts are contained in brackets e.g. does a*b have both opening and closing brackets. If that doesn’t work, try working from the outside in – start with the outermost pair of brackets and gradually work inwards.

When tweaking existing equations, it is also easy to accidentally delete a comma, particularly with long equations in which you have added lots of extra values and expressions.

PerlinCubic Equation Red Channel.JPG

Link to comment
Share on other sites

  • 1 year later...

Love the posts. 

I was trying for the fun of it and for learning purposes, as well as trying to break free of the builtin presets. To convert shaders from The Book of Shaders to simple static artwork in Affinity Photo. But I find it difficult to "convert" the small GLSL scripts or programs. Even though I have the documentation open https://affinity.help/photo/English.lproj/index.html?page=pages/Filters/filter_proceduraltexture.html?title=Procedural Texture.

Has anyone experimented with something similar and want to share some tips or insights? Thanks.

Link to comment
Share on other sites

I would recommend to open a new thread under Q&A, to keep this tutorial thread on topic.

you can tag me there @NotMyFault and I will answer all questions. 
In principle, you can create any color value (output) as a function with input parameters

  • pixel position (x, y)
  • color values of lower layers RGBA

using the set of functions listed in help.

Mac mini M1 A2348

LG34WK950U-W, calibrated to DCI-P3 with LG Calibration Studio / Spider 5

iPad Air Gen 5 (2022) A2589

Special interest into procedural texture filter, edit alpha channel, RGB/16 and RGB/32 color formats, stacking, finding root causes for misbehaving files, finding creative solutions for unsolvable tasks, finding bugs in Apps.


Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...

Important Information

Terms of Use | Privacy Policy | Guidelines | We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.