A Procedural Watercolor Brush Engine for Krita. GSoC project
Open, Needs TriagePublic

Description

Project Goals
I have already implemented it in the context of the course project, but the final application requires significant improvements and optimizations. As a part of my work I will do:

  • optimizing the speed of the algorithm, for example: adding R-trees (the rationale will be presented further);
  • transferring my code to Krita;
  • (future developments) adding High map for imitation different types of canvas.

Implementation
The basis for the implementation of the algorithm of the procedural watercolor brush is the article of the IEEE members: Stephen DiVerdi, Aravind Krishnaswamy, Radomı́r Měcn and Daici Ito, written in 2013. The solution is a dynamic system of constantly-updating objects. The main components of this system are splats and wet map.
A. Splats
The main idea of the implemented algorithm is the representation of a single brush mark as a combination of dynamic polygons (i.e. splats). Dynamic conversion of the splats simulates the movement of the pigment along the canvas. At each step, splat’s form changes by shifting its vertices. The direction of the displacement depends on several factors:

  • g - global gravity vector (imitation of slope of the canvas);
  • brush settings;
  • amount of fluid on canvas.

B. Wet map
The water adding to the canvas is realized through a wet map. It consists of a 2D grid of cells. Water does not move on canvas and is stored separately from the list of splats. Water can be added during the add splats to the system and individual action. The brush type specifies the size and shape of the region that is wetted by rasterizing a constant value into the wet map. This value represents the remaining amount of time each cell will stay wet. If the cell is already wet (i.e., has nonzero value) from an earlier stroke, its value is overwritten.
C. Lifetime Management
The life cycle of a splat consists of three stages: flowing, fixed and dried. At the very beginning the splat is in a state of flow. After several steps (the number is determined by the brush parameters), the splat stops moving and goes into the commit state. From this state, the splat can go either to the flow state or to the drying state. After some time of being in the fixation state, the splat goes into the drying state. In this state, the splat is fixed on the canvas and is removed from the simulation. Adding water transfers the splat from the fixation state to the flow state. When adding water, each vertex is checked for entry into a new wet zone. If this is so, then their velocities again become nonzero (see Fig. 1).

Fig. 1. Splat lifetime.
D. Brush types
To achieve the necessary effects of watercolor (were described above), 5 different brushes are needed: simple, wet-on-dry, wet-on-wet, blobby and crunchy (see Fig. 2). Each brush contains a certain number of splats in one stamp, located in a certain way. The diameter of the splat d depends on the width of the brush w. Also, for controlling the behavior of splats, different brushes have different values of:

  • r – roughness (in pixels, default - 1 px);
  • f – flow (percentage, default - 100%).
  • l – lifetime of splat (in steps, default - 30).

Fig. 2. Initial splat configurations. Left to right: simple, wet-on-dry, wet-on-wet, blobby, crunchy. Cyan outlines indicate the water region per-stamp.
Timeline
Work schedule

PeriodWork
22 May - 11 JuneThis is period of my exams in University. So I can work 7-11 hours per week.
11 June - 20 JuneThis is period of my summer practice. I can work 20-35 hours per week.
20 June - 28 AugustDuring this period I can work full-time on the project.
28 August - 15 SeptemberI can work full-time on the project for final steps.

Implementation schedule

PeriodWork
22 May - 28 MayI study the code for transferring my stand-alone implementation to Krita.
28 May - 11 JuneImplementation of the dynamic system and its main objects.
11 June - 18 JuneTesting and fixing system shortcomings.
18 June - 4 JulyImplementation of brush engines for all brush types.
4 July - 16 JulyMaking GUI for Watercolor brush. Discussion about it with community.
16 July - 10 AugustImplementation of height map.
10 August - 24 AugustMaking GUI and textures for simulation of different types of canvas.
24 August - 15 SeptemberTime for solving unexpected problems.

Details

Commits
R37:4fbea5b9f201: Fixed plane updates
R37:904af511be01: Added gravity support. Fixed stroke finishing when close program bug.
R37:70c230631c70: Merge remote-tracking branch 'origin/master' into tantsevov/T6224-watercolor
R37:4686b41c0c38: Some bug fixies: Fixed incorrect removing splats from cached plane Removed lod…
R37:e38f31d909a2: Remaked painting mode and added updating settings
R37:aeb12e071ba5: New planes logic
R37:085308f1dc79: Added an update of the system in between the strokes. Added bugs with jobs
R37:b424f2f42f54: New planes' and generators' logic
R37:be22fcba6878: Add planes for all states
R37:00be5db7d138: Render static splats in another paint device (for ceshing)
R37:6bbb0086a46f: Added color updating
R37:fda6f4333072: Merge master
R37:ebc66fa55ef0: Fixed falling after using ColorPicker by using Ctrl
R37:af2c742bbb4e: removed tests from building
R37:c7a33a5a524d: Added some impl for "infinity" stroke for watercolor undo engine.
R37:233d96757801: Color bug fix
R37:ca5484bc0dd2: Splats deform only during stroke. Random color change...
R37:4e1022cd104d: Added basic preset for work with engine. But it works slow and only during…
R37:49c6a9a17b5e: Make strategies for different brush types
R37:57fb68360184: Make build work correct
R37:4ab80a7b1caf: Start for making plugin
R37:b16d6240f996: Added generator and unit test for it.
R37:cb55d2744d3e: Add test for splat and change wetmap realization
R37:13f0214ba724: Changed wetmap realisation and maked some tests for splat
R37:96d94e35494c: Add Unit-test for wet map
R37:a86557663d72: Added license heads and header for exporting wetmap for testing
R37:96f5b06d1180: Add splat generator for future testing of basic engine.
Restricted Application added a subscriber: woltherav. · View Herald TranscriptMay 29 2017, 9:21 AM

I saw your post on undo & new stuff. It looks very promising! I'm sure you're thinking about this, but I hope you're not going to stick with round blobs for the dab :P. So for the undo, I'm not sure if it's even possible, but I'd explore how things are handled in Corel Painter as that's the only other app out there(?!) that has watercolor simulation. I can't test it cause I only have linux, but I'd go and download a free trial version and I'd explore it a bit if I were you. I think what they do (which is something I read here - https://skipallenpaints.com/2015/04/04/working-with-a-very-wet-watercolor-variant-in-corel-painter-2015/#comment-35600, but I might have understood poorly). Is that they have a special layer for watercolor and the undo operation is for... the entire layer?! Which is just an erase operation now that I think about it.

Anyway... that's my suggestion, try corel painter :)

I saw your post on undo & new stuff. It looks very promising! I'm sure you're thinking about this, but I hope you're not going to stick with round blobs for the dab :P. So for the undo, I'm not sure if it's even possible, but I'd explore how things are handled in Corel Painter as that's the only other app out there(?!) that has watercolor simulation. I can't test it cause I only have linux, but I'd go and download a free trial version and I'd explore it a bit if I were you. I think what they do (which is something I read here - https://skipallenpaints.com/2015/04/04/working-with-a-very-wet-watercolor-variant-in-corel-painter-2015/#comment-35600, but I might have understood poorly). Is that they have a special layer for watercolor and the undo operation is for... the entire layer?! Which is just an erase operation now that I think about it.

Anyway... that's my suggestion, try corel painter :)

thanks, I know about corel painter, but i didn't know about free trial =) i will check it

This might be something to think about... I just tried switching to this branch and I am having a problem with it.

  1. start krita
  2. create a new document

Krita crashes with a "bus error"

This is the most my gdb will tell me

Thread 1 "krita" received signal SIGBUS, Bus error.
0x00007ffff5e5e4bc in QtSharedPointer::ExternalRefCountData::getAndRef(QObject const*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5

This might be something to think about... I just tried switching to this branch and I am having a problem with it.

  1. start krita
  2. create a new document

    Krita crashes with a "bus error"

This is the most my gdb will tell me

Thread 1 "krita" received signal SIGBUS, Bus error.
0x00007ffff5e5e4bc in QtSharedPointer::ExternalRefCountData::getAndRef(QObject const*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5

Did you built "tantsevov/T6224-watercolor" branch, or "tantsevov/watercolor"? Now I work on first one.

I think I was working on the first one. I am having some odd build stuff going on though which I think is because of QtCreator overriding my cmake files. My report might not be right. I will try to build again later.

Don't know how this stuff is going, but if you're still working on it you might be interested in this to snatch ideas or maybe collaborate?! maybe.... just... maybe :D http://www.taron.de/forum/