Thursday, 31 January 2019

How to work with Brush Dynamics for a Bokeh effect

In the next post i want to show you how to make a Bokeh effect in Gimp, but before that can happen we need to talk about Brush Dynamics and custom brushes.

Brush Dynamics are probably the most powerful feature in Gimp, but also a bit hard to understand because the functionality is quite esoteric and hidden deep inside the program.

So lets start with a custom brush. You may already know how to make one but bear with me, because there are a few concepts i'd like to talk about, which will help understanding Brush Dynamics.

For the upcoming Bokeh effect we will need a custom brush, that looks like a circular light with a halo.

Im using Gimp 2.10.8 but Gimp 2.8 should work the same.

Anatomy of a custom brush

The most important trick to make a brush that can take any color is to make it greyscale !

This greyscale brush works like an inverted layermask.

Everything black will be painted in the colour you chose in the Color Area. Its the stamp.

Everything white will take no colour and everything greyscale will paint transparent.

Lets try this:

Gimp Brushes dont scale very well. So unlike Photoshop, bigger is not better. Gimp brushes work best when only scaled by small amounts (apparently that is some sort of bug and might change in the future).
EDIT 03.2020: this bug has indeed been fixed in Gimp Version 2.10.18 with the inclusion of mipmaps for brushscaling. I still recommend trying the tutorial with the brush dimensions i used.

I want my actual Bokeh light to be approx. 20px in diameter.

1. Create a new document 40x40px and make the backgroundlayer white.

2. Go to 'Image → Mode' and choose Greyscale !

3. Create a new transparent layer on top, go to 'View' and make sure 'Snap to Canvas Edges' is active.

4. Zoom in real close (like 800%) and make a circular selection with the help of snapping.

5. Next check 'Expand from centre' and 'Fixed Aspect Ratio' in the 'Elliptical Selection Tool Options', then resize the selection to 20px.

6. On the transparent layer, fill this circular selection with black, then convert the selection to a path ('Selection → To Path') and deselect.

7. We want our brush to pick colour but also have transparency, so we reduce the Opacity of the brushlayer.

I prefer Bokeh effects with bright lights on a dark background, but vibrant colours will quickly look greyish and dull when the transparency is too high, so we will have to choose the Opacity wisely.
80% might be a little too opaque, so i will go with 65-70%.

8. For the halo we add a fully opaque stroke in black.
Add a new layer and stroke it from the Paths-Tab. 2px width.

9. Before we merge the layers and export our new brush, i want to talk about an important detail that will help you understand Spacing, Jitter and the concept of the Bounding Box better.

The Bounding Box

As you can see, the image in its current state is bigger than the part of the brush that will be visible when painted. We could crop it or leave it as it is.
If we dont crop it, the extra white does not show while painting but acts as a built-in 'Spacing'.

'Spacing' is not only defined by the chosen value in the export process, but also the 'Bounding Box'.

In the image below, the dashed red line represents the 'Bounding Box'.
On the left side a brush with the extra Spacing of the bigger 'Bounding Box' and on the right a tighly cropped brush.

When we paint a brushstroke, the 'Spacing' dictates the intervals at which a brushstroke is painted.
Spacing is a percentage of the 'Bounding Box' of the brush.

A tightly cropped brush will paint each brushstroke next to the other when the 'Spacing' is 100.

At a 'Spacing' <100, we will get an overlap of brushstrokes and with a 'Spacing' of greater than 100, we will get space between the strokes.

As you can see, the behaviour of these two brushes is slightly different. all depending on the size of the 'Bounding Box'.

We can compensate a big 'Bounding Box' with a decrease of 'Spacing' in the 'Tool Options', when painting.

Understanding 'Bounding Boxes' and 'Spacing' can also be useful for other projects.
For example when you have a really tiny brush of 4px diameter and you want to fill a whole canvas with "particles" (like little stars).
Getting this tiny brush spaced out, requires a lot of 'Spacing' and 'Spacing' is limited to 5000.
So adding a much bigger bounding box to this little 4px dot can be a really good idea.

Exporting the brush

10. With all this in mind, we merge the layers and then export as a .gbr file.
If you use ofnuts' Add-on Collection Manager like me, its important to switch off the brush folder you want to export to, before exporting. If you dont use an Add-on manager, you export to the Gimp brush folder.

For Gimp 2.8, thats:


and for Gimp 2.10 its:


After you hit 'Export', Gimp opens another pop-up window where you can enter the name of the brush (perhaps with more detail) and enter the 'Spacing' you want to give your brush.
For painting lines its mostly 1-10 and for brushes that dont require overlap, 100. Whatever you chose, its just the default and can be changed on the fly in the 'Tool Options'.

After a refresh, the brush should appear in your Brushes Tab.


Now its time to test the brush and introduce 'Jitter'.

We can draw lines of little halos with space between the brushstrokes at default 'Spacing' and lines of overlapping circles when we reduce the 'Spacing'.
But to paint the little circles in a more chaotic way, spread all across the canvas, we need to use the 'Apply Jitter' option.

When you check the box in the 'Paintbrush Tool Options', a slider is revealed that lets you select the 'Amount' of 'Jitter'.

The 'Amount' of 'Jitter' displaces each brushstroke by a random value on the vertical. The maximum displacement is calculated like this:

Brushsize + (Brushsize x Amount)

So a 20px brush with a 3 for the 'Amount' will displace the brushstrokes by 80px.
40px to the top and 40px to the bottom.

You can easily test this by stroking a path repeatedly with a brush.
After a while you will get a rectangular block in the exact size of the calculated Jitter-Amount.

Choosing the best 'Amount' of 'Jitter' might seem difficult, thats why its important to always do a test brushstroke and play around with the options.
If you want to fill a canvas with lots of broad sweeping brushstrokes, a big 'Amount' of 'Jitter' might be a good idea (like 5-10), while when you want to paint short controlled brushstrokes, go with a lower value (like 2-3).

So now we can paint something like this in the image below:
we get transparency from the custom brush, spacious or tightly packed depending on the 'Spacing' and spread all over the canvas with 'Jitter'.

But it all still looks a little uniform. The only way we can have variation is to change values and colours manually and paint some more.
This is where Brush Dynamics come into play.

Brush Dynamics

In your 'Paintbrush Tool Options' there is a 'Paint Dynamics' button. When you click it, a list of Brush Dynamics opens.
These come installed with Gimp (and can not be edited).

You can add your self-created Brush Dynamics with the 'Paint Dynamics Dialogue'.

To open it, go to 'Windows → Dockable Dialogues → Paint Dynamics'.
At the bottom of this dialogue is a button to create a new 'Dynamic'.
When you click it, a 'Dynamic' named 'Untitled' appears and the 'Paint Dynamics Editor' will pop open.
Rename it from 'Untitled' to 'All Purpose'.
Because the list is ordered alphabetically, everything starting with an 'A' will appear at the top, which makes it easy to find in the 'Brush Dynamics' list.

From now on we will only work with this single Brush Dynamic and change it on the fly to our needs.

Close the 'Paint Dynamics Dialogue', then drag and drop the 'Paint Dynamics Editor' into your Tabs Panel. I have it next to my Brushes, Gradients, Patterns and Fonts.

(your Gimp might be customized in a different way)

Now you also understand what i meant when i said the Brush Dynamics are a somewhat hidden feature...;)

Lets try to customize our 'All Purpose' Dynamic so that we get a random size and a variation of color.

In the 'Paint Dynamics Editor' check the boxes at the intersection of Random, Color and Size.
(make sure the Dynamic is switched on in the 'Paintbrush Tool Options' !)

Before you can make a teststroke, make sure to click the little plus so the 'Dynamics Options' in the 'Paintbrush Tool Options' are open. Choose a gradient from the 'Colour Options'.
I used the hardedged two-color gradient with fully saturated colors to compensate the black background and the transparency of the Bokeh Brush.

This is the result of the teststroke. The 'Random Colour' Dynamic picks the colours from the gradient.

You can also use shades of the same color with a normal 'FG to BG' gradient for a more subtle effect.

You might notice, the size of our little halos varies from tiny to normal and i'd like to influence how small a single brushstroke gets.

This is the ultimate level of the brush dynamics:
if you have a look at the 'Paint Brush Dynamics Editor', there is a little drop-down menu, where it says 'Mapping matrix'.
When you change it to 'Size', the look of the dialogue will change to a coordinate system.
Make sure 'Random' is not only ticked but also highlighted blue !

The coordinate system is divided into eight rows and columns. Every square represents 12,5%.
On the left we have 'Size' and on the right 'Random'.
We can change the graph and control the behaviour of the randomness.

I dont want any tiny brushstrokes.

To exclude all tiny brushstrokes, all i have to do is change the point of the Size-graph to something higher.
So for example, if i set it to the middle of the left side, the minimum size of the brushstroke will be limited to 50% of the original brushsize.

This is the result and as you can see, the circles have a lot less variation in size.

That concludes this tutorial about custom Brush Dynamics.
In the next post, i will show you how to combine multiple layers of randomly painted circles into an atmospheric Bokeh effect with the help of filtering.

No comments: