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.
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.
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).
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).
|22 May - 11 June||This is period of my exams in University. So I can work 7-11 hours per week.|
|11 June - 20 June||This is period of my summer practice. I can work 20-35 hours per week.|
|20 June - 28 August||During this period I can work full-time on the project.|
|28 August - 15 September||I can work full-time on the project for final steps.|
|22 May - 28 May||I study the code for transferring my stand-alone implementation to Krita.|
|28 May - 11 June||Implementation of the dynamic system and its main objects.|
|11 June - 18 June||Testing and fixing system shortcomings.|
|18 June - 4 July||Implementation of brush engines for all brush types.|
|4 July - 16 July||Making GUI for Watercolor brush. Discussion about it with community.|
|16 July - 10 August||Implementation of height map.|
|10 August - 24 August||Making GUI and textures for simulation of different types of canvas.|
|24 August - 15 September||Time for solving unexpected problems.|