There is an open drawing project, called Alchemy. I noticed this project while watching some video tutorials made by David Revoy. He uses this tool in his workflow. I noticed that people can draw crazy interesting stuff with that tool. I wanted to have those features in Krita for our users. I also wanted to kill Alchemy in David’s workflow (evil laugh) so that he can use Krita more in his workflow.
Here is the vision of the Alchemy project, just for the reference and before I kill the Alchemy userbase with Krita (exaggeration of course):
Alchemy is an open drawing project aimed at exploring how we can sketch, draw, and create on computers in new ways. Alchemy isn’t software for creating finished artwork, but rather a sketching environment that focuses on the absolute initial stage of the creation process. Experimental in nature, Alchemy lets you brainstorm visually to explore an expanded range of ideas and possibilities in a serendipitous way.
Now is the time to mention our shiny Krita vision:
Krita is a KDE program for sketching and painting, offering an end–to–end solution for creating digital painting files from scratch by masters. Fields of painting that Krita explicitly supports are concept art, creation of comics and textures for rendering. Modelled on existing real-world painting materials and workflows, Krita supports creative working by getting out of the way and with snappy response.
David Revoy’s workflow contains mainly shape and mirroring mode from the Alchemy. So I started and focused on those features and I tried to implement their adaption for Krita. There are other features in Alchemy, that are nice to have, but my spare time is limited so I prioritize!
Let me share some developer details. First let’s talk about the shape feature. Basically it allows you to paint the freehand form shape. Every new mouse move adds triangle to the shape, but some triangles make the shape non-convex and that means that the shape is transparent in the place where the triangle bisect the shape.
Piece of abstract art demonstrating
non-convex freehand shape
Alchemy is vector graphics application, Krita is raster graphics. First problem was how to render the shape correctly with raster brush. I wanted to create some new brush engine — it is possible to realize this feature like this, e.g. Pinta can do this shape with its tools. But, but..brushes just leave the trace, how do you want to render the shape, which is changing under your hand like some kind of animation as you stroke? I did not shared yet that the shape can be pre-processed and post-processed which imply that it can change from dab to dab. The opacity of the shape can be dynamic too, it can be like random, controlled by pressure. Dmitry, Krita folk, had nice idea to use mean of the pressure, because when you activate the opacity contoller with pressure, you will not see the shape, because the sensor pressure sends low value when you raise your pen from the tablet.
Made with shape and mirroring
By me and my pc mouse
The solution I come up with is to first render the part of the stroke, next time erase the previous part of the stroke and render the whole stroke (previous and new) again on the unchanged background. We call some part of the stroke dab.That way the opacity can be dynamic, shape can change as it will be re-rendered everytime from the beginning.
Implementation details (feel free to skip): The rasterization is done by QPainterPath and QPainter and the result is used as alpha mask for our various color-spaces. Thank you, Qt. First attempt was using data that we store to our pixel buffers for undo action, we name it oldRawData(). Also pixel filters use those data sometimes. Before the stroke begins, you have the original unchanged data of the layer there until the end of the stroke – those are there because of the Krita’s transaction system. The whole stroke is one transaction for every brush engine. This attempt somehow worked, but it was slow. I pinged Dmitry, our transaction, tile engine and multithreaded developer and he advised me to make copy of the current layer and use those data to erase rendering of the previous dab. I used some tricky commands that activated the tile sharing of the pixel buffers and auto-magically it was much more faster. The only problem that left was some flickering. Also the speed was still not perfect, but closer to “snappy response” (see Krita vision). Next advice from Dmitry was to use transaction directly. Cyrille Berger advised this in the beginning, but somehow I did not know how to realize that idea and Dmitry showed me some pseudo code with those transactions. Lesson learned: ask for the pseudo-code. I implemented the advice. All the rendering was done on the layer directly. That caused that flickering of the canvas. So I had to do some kind of double buffering. Now all rendering is done on the internal device which is the copy of the layer and the flickering is gone. Speed is almost ok, there is no more flickering.
Another interesting and funny feature is mirroring of the stroke. You paint on the left half of the canvas and the stroke is rendered also on the right half and it is mirrored. Crazy fun.
You want to paint two mirrored Batmen?
Yes, you can…with Krita!
I implemented this feature first for the brush engine that has features from Alchemy (the shape feature described above) as it is needed for David workflow. I realized soon that this can be generalized and done in our freehand tool, that means for every brush engine, that we have. Yes, now we have two buttons in the tool bar for vertical and horizontal mirroring. This mirroring is implemented as dab mirroring. When you smudge the pixels in your canvas or if you deform them with our brush engines, the pixels beneath your cursor are used. The result of the brush is mirrored and placed in the correct mirrored position., but the smudge or deform is not done on the image. It has it’s purpose too. It’s fast, and it’s fun also.
Red icons turn on the mirror feature (Krita 2.4 alpha)
Some of our artists usually use git master, so that they have the candies like mirroring faster, so I’m glad that I can share already some art produced with mirroring feature:
Some tests done by David Revoy in Krita with mirror feature:
Ok, but I want to mirror the behaviour, I want to smudge or deform both sides! maybe you say, dear Krita user. You want to smudge both sides of the image and mirrored. For that I created a new tool for you dawg. Tool, that does not mirror the result, but mirrors the stroke of the freehand tool. But about that in some future blogpost.