Bug 322839 - Brush engine antialiasing
Summary: Brush engine antialiasing
Status: RESOLVED FIXED
Alias: None
Product: krita
Classification: Applications
Component: Brush engines (show other bugs)
Version: 2.8 Pre-Alpha
Platform: Kubuntu All
: NOR normal
Target Milestone: ---
Assignee: Krita Bugs
URL: http://www.odysseus-art.com/files/for...
Keywords:
: 330353 (view as bug list)
Depends on:
Blocks:
 
Reported: 2013-07-26 10:10 UTC by Odysseas
Modified: 2014-09-02 10:45 UTC (History)
6 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments
Small brush diameter in Photoshop (125.47 KB, image/jpeg)
2013-08-08 21:58 UTC, Odysseas
Details
Attempt at making perfectly maintaining softness-brush. (71.08 KB, application/octet-stream)
2014-01-14 19:13 UTC, wolthera
Details
Very large attempt at the same. (66.87 KB, application/octet-stream)
2014-01-14 19:29 UTC, wolthera
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Odysseas 2013-07-26 10:10:24 UTC
This is an issue I have been experiencing in all the Krita versions from 2.6 until 2.8, both in Windows and Linux.
In the picture example I use a gaussian autobrush with precision 5. I used the most simple settings and no variability in size or opacity, in order to demonstrate the issue better.

If I add a small amount of fade, the x100 sized stroke is nice and smooth. However, the x10 is still pixelated. Even if I soften the edges more, the jaggy line is there, and the brush becomes too blurry anyway - so this is no solution.

Example with 0.90 fade:
http://www.odysseus-art.com/files/forums/misc/brush%20antialias-fade.jpeg

So a stroke with size x100, set on pressure, will be pixelated when small, and smooth when it gets bigger.

Please note that I am not referring to the smoothing of the stroke curve - which would point to the smoothing options. This is about the line quality itself.
I have tested this with all the autobrushes in various settings and also with custom brushes. Some workarounds and fine-tuning can definitely be done: like combination of fading, lower opacity in low pressure, textures. Also the softness control seem to be for that reason, but I find that it works inconsistently.

No matter the workaround, the issue is still there. I think this is a very important point to focus on - probably more important than many other feature improvements.

Reproducible: Always

Steps to Reproduce:
1. Draw with a 'hard edged' brush, preferably in small size
Actual Results:  
The line in small sizes is pixelated/jagged

Expected Results:  
The line is smooth and consistent in all sizes
Comment 1 Dmitry Kazakov 2013-08-08 19:43:10 UTC
Hi, Odysseas!

Do you mean the line with small diameters has hard pixelated edges or you mean that the line moves in zigzag'ish way?

The second bug might be already fixed in master. Tomorrow in the morning Krita Lime PPA (Raring *only*)  will be updated up to current master, where the huge refactoring for the brush engine has happened. If you have Kubuntu Raring, could you also check this?

PS:
Note, Precise and Quantal versions of the repository will *not* be updated due to technical reasons :(
Comment 2 Odysseas 2013-08-08 21:55:03 UTC
Hi Dimitry, 

I am talking about the pixelated edges in small diameters. I spent quite some time trying to figure this out in Krita and testing in other software to see how their brush engines work. I consider photoshop to have the most smooth performance and brush system, and here is an interesting thing I observed:
Photoshop uses also a default "round" brush tip which can be squeezed or softened. I tried to see how it behaves in small diameters, so I created a brush with 100% hardness and no smoothing. 
I painted some lines with constant size and some with size controlled by stylus pressure.

As you will see in the link, the constant diameter stroke  is quite pixelated with diameter 1, probably less than krita though. Bigger diameters are nice and smooth.
Now the interesting part: When I set the size on pressure, the small diameters (1-2 px probably) get automatically "smoothed". I think that in this size the stroke is less opaque, and maybe with softer edges. If the stroke exceeds the threshold size of 1-2 pixels, it gets fully opaque and smooth.
See the link to understand better what I am talking about.

I tried to create something similar in Krita, tweaking the tip softness and combining softness and low opacity set on pressure. It works quite well in small diameters. Increasing the size with these settings produces a soft brush with low opacity when pressing lightly, so one needs two or more brushes to achive the smooth look of the photoshop example.

I have installed the lime version in Kubuntu 13.04. I am quite new in linux, but when I last updated some days ago I saw the word "Raring" in the update description so I guess I 'll be able to get this one as well. If I am utterly confused about this I apologise, let me know please!

Good to know about the update, I can't wait to see the improvements. Thank you for all the hard work!!
Comment 3 Odysseas 2013-08-08 21:58:43 UTC
Created attachment 81611 [details]
Small brush diameter in Photoshop

Example of the way Photoshop handles small brush diameteres.
Opacity is 100%, hardness 100%
The first 2 have constant size, the others pressure controlled size. The numbers at the bottom indicate the brush size.
Comment 4 Halla Rempt 2014-01-04 11:41:06 UTC
Thanks for the extra info.
Comment 5 wolthera 2014-01-14 13:15:52 UTC
I can sort of confirm this bug, and I can also tell you all open-source software have this issue. I myself always do some trickery with the hardness-options and the pressure to get this consistent on a preset.

However, there is one open source brush-engine which does seem to behave properly: The ink tool in Gimp. I suspect it does some kind of vector-trickery though, and it has no hardness-parameter.

I think photoshop(and a plethora of japanese software) somehow manages to have the hardness set as a sort of 'absolute' softness instead of proportional, starting from the edge going inwards. This would make 1 pixel brushes with this method semi-transparent, even if the opacity is 100%(and unaffected by other parameters but this softness)

/just a theory

I would set this to a wish, because while it's expected behaviour, and intuitive behaviour, it is not a mistake in the implementation of the system.
Comment 6 Halla Rempt 2014-01-14 13:28:21 UTC
It looks to me then as if the Photoshop brush engine replaces the stroke 
after it's ended with a rasterized vector stroke. I.e., instead of using
the image produced by the accumulated dabs, it re-renders the stroke using 
a vector tool and then rasterizes that. If true, it might be visible when 
doing a stroke in photoshop, with ragged edges visible while painting
and those getting smoothed out when done with a stroke.

Krita, if you compile Karbon, also has a vector calligraphy tool with
smoothing -- that should have the same properties as gimp's.
Comment 7 wolthera 2014-01-14 13:50:00 UTC
Unfortunatly, this is probably not the case.

Photoshop does know 'spacing', 'flow', 'jitter' and textured dabs, all hallmarks of a dab-based brush system.
Comment 8 Dmitry Kazakov 2014-01-14 14:28:51 UTC
Probably, Photoshop changes the fading curve with the size of the brush...

Wolthera, could you experiment with the curve of the 'Soft Brush' engine and try to get the brush of a smaller size with the look exactly as you want? Is it possible at least? If yes, then we should probably experiment with the formulas we use in the mask calculation thing.
Comment 9 wolthera 2014-01-14 19:13:34 UTC
Created attachment 84648 [details]
Attempt at making perfectly maintaining softness-brush.

Oh, uhm, both me and Animtim have made attempts at it, and a variety is part of the standard brushes(As inking brushes), though a couple of mine aren't and can be found in the resources forum('inking brushes for Krita')

That said, I attempted making one just now. It uses not only the softness->pressure, but also some opacity->pressure and a little spacing->pressure.
The hardest challenge is getting the very tiny sizes (10<, and especially 1<) render as something else than a fully opaque black pixel, which is why the spacing and opacity are used.
Spacing for making sure the dabs don't clutter the softness out of each other by being stacked, and opacity for those tiny sub-pixel sizes.

It's fairly similar to gimps ink-tool now. Though my judgement is horrible. /spent an hour trying to determine whether the anti-aliasing was perfect or not >_<
Comment 10 wolthera 2014-01-14 19:29:35 UTC
Created attachment 84649 [details]
Very large attempt at the same.

Of course, it is ruined as it is resizes, so here's an attempt that's about 5 times bigger, but doesn't have the 1< lines as nice(I turned off transparency because I couldn't get the required fine-tuning done within the ui)
Comment 11 Halla Rempt 2014-01-28 11:29:26 UTC
*** Bug 330353 has been marked as a duplicate of this bug. ***
Comment 12 Paul Geraskin 2014-01-28 14:09:06 UTC
The same bug https://bugs.kde.org/show_bug.cgi?id=322839
Comment 13 animtim 2014-02-19 11:07:42 UTC
My opinion on this issue is that we could have a new brush engine like the ink tool in gimp that produce size-independant nice anti-aliasing for line work.

I think the way pixel brush works now is useful too and shouldn't be replaced, and so adding this to a new specific brush engine may be easier to code and easier to use than adding some more options to current pixel brush.
Comment 14 Paul Geraskin 2014-02-19 11:13:40 UTC
Hello AnimTim. 
I disagreed with you. This is a big bug. PS and gimp works ok for resized brushes. So it must be fixed.
Comment 15 Paul Geraskin 2014-02-19 11:28:26 UTC
I did another test o proove the issue:

I did a clipboard brush with Spacing=10(Krita) and GimpBrush with Spacing=5(Gimp).
http://i.imgur.com/Qy6vye0.png

Brushes are not scalable at all.
Comment 16 Halla Rempt 2014-02-19 11:32:15 UTC
To me, it almost looks like a rounding error when selecting the next dab size from the pyramid.
Comment 17 animtim 2014-02-19 11:53:46 UTC
After checking again gimp's brushes, I see they are quite different than krita's pixel brush, but not really better, more different.

Also it looks like the difference between the "pencil" and the "brush" tools in gimp.
Looks like our brush engine is more like the pencil tool not adding extra anti-aliasing (and so allowing pixel-perfect brushes), so we would need a new mode acting like their brush tool regarding anti-aliasing..

I still think current brush system has a better "natural painting" feel than if it had always such perfect-linear-anti-alias , which is good in some brush case of course but gives a more synthetic look.
Comment 18 Paul Geraskin 2014-02-19 12:34:17 UTC
Ok, Dmitry gave me a patch for AutoBrush. http://pastebin.com/YBF2vJi6

My tests:
With Patch - http://i.imgur.com/Kle01Xh.png  http://i.imgur.com/GTRofVA.png
----
Without Patch - http://i.imgur.com/IhjiFqt.png 
Gimp - http://i.imgur.com/yqUpJGS.png

BUT THIS IS ONLY FOR AUTOBRUSH!  Now autobrush is perfect.
Comment 19 Paul Geraskin 2014-02-19 12:46:38 UTC
Boud - Dmitry said you are semi-right :) The issue is in Spacing also. :) So i hope this bug will be fixed for all brushes in future.
Pixel brush still has issue even with the patch. 
Gimp- http://i.imgur.com/yqUpJGS.png
Krita- http://i.imgur.com/iOwD6mC.png

Animtim - I again disagreed with you. :) The bug is just a mistake. It will be fixed in future when Dmitry will have some time.
Comment 20 Dmitry Kazakov 2014-02-19 12:52:17 UTC
Just want to add that the patch is only a proof of concept. It shows that the problem is either of:

- The size of the dab should be a bit bigger than diameter of the brush to handle aliasing
or/and
- the dab is offset wrongly (?)
or/and
- the spacing of lower sizes should be bigger than usual to get a good quality

all the three theories are not checked yet. And yes, the patch breaks predefined brush
Comment 21 wolthera 2014-02-19 12:57:53 UTC
Okay, confirmed this in IRC, summary of the problem:

What I think is going on is two seperate issues:
1. The current system, when scaling down, has rounding errors. So a soft brush at size 1 become a black pixel regardless of brush softness.
2. The brush engine softness is PROPORTIONAL. This means that a perceptually perfectly sharp brush at size 20 looks super soft on size 100. This is NOT undesirable behaviour, but rather unexpected. (And this same brush would be almost aliased on size 5).

With my limited programming knowledge, I think 1. is the most difficult one to solve, but will make a lot of people really happy.
2. shouldn't be difficult to solve, but it's probably an idea to have it as separate generated brush-tip? Like, we have 'default', 'soft' and 'Gaussian'... I guess this would be 'absolute' or something? That uses an absolute value instead of a proportional value for brush softness?

EDIT: Okay, it'll be called auto-brush.
Yes, spacing will also affect the brush. This is due to the dabs overlaying each other and affecting the softness due to transparencies overlapping.
Comment 22 Paul Geraskin 2014-04-17 10:36:30 UTC
Hello again.

I did some tests in PS and Krita for Dmitry.

Here is brushes and presets for Krita:
https://dl.dropboxusercontent.com/u/26887202/Krita/krita_antialiasing_test.zip
Just copy everything in Krita and take "round_200px" and "round_autobrush" presets to test.

Here is comparison:
http://i.imgur.com/l2xIF67.png - the same preset "round_200px" in PS.
http://i.imgur.com/ddob6c7.png - "roud_200px" in Krita.
http://i.imgur.com/fykcaG3.png - "round_autobrush" in Krita.
Comment 23 Dmitry Kazakov 2014-09-02 10:45:35 UTC
Git commit b7812a6efe437fd1b8eb956a399dbd14ea5e3800 by Dmitry Kazakov.
Committed on 02/09/2014 at 10:39.
Pushed by dkazakov into branch 'krita-chili-kazakov'.

Remove rounding of the brush scale

It was incorrect to round the brush scale, because it affects the
precision of the line. The bug was not seen in auto brushes, but
it affected Predefined Brushes, since they use the resulting transform
directly.

M  +0    -9    krita/libbrush/kis_qimage_pyramid.cpp

http://commits.kde.org/calligra/b7812a6efe437fd1b8eb956a399dbd14ea5e3800