Bug 290383

Summary: Deform Brush leaves whitish or darkish traces in 16-bit, if scrub long enough on the gray field
Product: [Applications] krita Reporter: ALeXeY <alexeyn3d>
Component: Brush enginesAssignee: wolthera <griffinvalley>
Status: RESOLVED FIXED    
Severity: normal CC: dasaan.san, dimula73, GBirdboy, griffinvalley, halla
Priority: NOR    
Version: 2.4-snapshots   
Target Milestone: ---   
Platform: Compiled Sources   
OS: Linux   
Latest Commit: Version Fixed In:
Attachments: Bug appearance in RGB
Bug appearance in CMYK

Description ALeXeY 2012-01-02 11:15:45 UTC
Created attachment 67334 [details]
Bug appearance in RGB

Version:           2.4-snapshots (using KDE 4.5.5) 
OS:                Linux

While using Deform Brush in 16-bit mode, there is some modification (or degradation) of color occurs. This was observed on a neutral gray background. Where, in the RGB mode, the brush leaves whitish traces, and in the CMYK mode, darkish. I tested it in different Color Profiles (not all), regardless of this, the bug appears.

In the 8-bit mode, it's (as I can see) a normal behavior: no whitish traces, just deform. 

Reproducible: Always

Steps to Reproduce:
1 Create a new document in 16-bit mode, Canvas Color: neutral gray (128,128,128).

2 Scrub with Deform Brush (default preset) in about 10-20 sec.

Actual Results:  
Color changing, while deforming long enough. 

Expected Results:  
Deform Brush must just deform, without color modification. 

Ubuntu 10.10, Krita 2.4 Beta 5, 
versions tested: v2.3.84-725-gb7f79d3 and v2.3.84-527-gbd5afaf 
(Format is: Version number - revisions since the version number - git hash)


----------------------------------------------------------------------
I'm not a skilled programmer and I have not looked the code, but let me express my humble opinion. For me, it's looks like some rounding of numbers (16-bit --> 8-bit --> 16-bit or something like) take place. 

And, please, excuse my English.
Comment 1 ALeXeY 2012-01-02 11:17:16 UTC
Created attachment 67335 [details]
Bug appearance in CMYK
Comment 2 Halla Rempt 2012-01-02 12:14:35 UTC
Ack -- thanks for the report!
Comment 3 Kubuntiac 2012-01-03 02:31:56 UTC
Just confirming the same result on:

Kubuntu 11.10
KDE 4.7.3
FGLRX (withopenGL canvas turned on and off)
Trunk Krita as of today
Comment 4 dasaan.san 2013-11-02 22:31:14 UTC
Unable to reproduce the effect seen in the screenshots with Krita 2.6.4 and KDE 4.10.5
Comment 5 Halla Rempt 2015-04-16 18:59:04 UTC
If you disable bilinear interpolation, the effect won't happen, with bilinear enabled, it will happen.
Comment 6 Dmitry Kazakov 2015-06-21 10:26:11 UTC
I cannot reproduce it anymore. Both with and without bilinear interpolation.

Could you check if it is still valid?
Comment 7 Dmitry Kazakov 2015-06-21 10:27:25 UTC
Ah, sorry, forgot about 16 bit. Confirmed. 16-bit more is mandatory to reproduce the bug.
Comment 8 vanyossi 2019-06-24 03:14:42 UTC
Git commit bd9602f5229badd80cde58a89198d21e903fa388 by Ivan Yossi.
Committed on 24/06/2019 at 03:14.
Pushed by ivany into branch 'master'.

Avoid rounding coords for hue and value on bilinear sampleData

M  +33   -16   libs/image/kis_random_sub_accessor.cpp
M  +2    -1    libs/image/kis_random_sub_accessor.h

https://invent.kde.org/kde/krita/commit/bd9602f5229badd80cde58a89198d21e903fa388
Comment 9 Halla Rempt 2019-06-24 08:21:48 UTC
Git commit 04ff8ad4cc2a976e80c6c5d5326e09a08a36d770 by Boudewijn Rempt, on behalf of Ivan Yossi.
Committed on 24/06/2019 at 08:21.
Pushed by rempt into branch 'krita/4.2'.

Avoid rounding coords for hue and value on bilinear sampleData

M  +33   -16   libs/image/kis_random_sub_accessor.cpp
M  +2    -1    libs/image/kis_random_sub_accessor.h

https://invent.kde.org/kde/krita/commit/04ff8ad4cc2a976e80c6c5d5326e09a08a36d770
Comment 10 vanyossi 2019-06-28 17:26:22 UTC
had to revert the fix as it broke many other transformations.
Comment 11 vanyossi 2019-06-28 20:13:19 UTC
The issue with deform is that it mixes the alpha channel of the layer and the dab, using the subpixel information as weight data. as far as I understand, when the mix is done in the deform brush case there is alpha at 100 in one channel which in repeated strokes causes the paint to go invisible.

Is this intentional?
Comment 12 Halla Rempt 2019-06-29 12:53:20 UTC
At this point in time, I don't think anyone knows. You could try to go through the git history and see when that was added, but you might need the calligra-history git repo to do that.

If all else fails, we can copy your fix into the deform brush and make that the only user of this code.
Comment 13 vanyossi 2020-02-28 03:42:29 UTC
*** Bug 418271 has been marked as a duplicate of this bug. ***
Comment 14 wolthera 2020-07-24 09:17:46 UTC
Git commit 15b1ebf076f476b399161d5928419b7be106c568 by Wolthera van Hövell tot Westerflier.
Committed on 24/07/2020 at 09:06.
Pushed by woltherav into branch 'wolthera/BUG-290383-colormixopfix'.

Fix deform brush by making KoColorMixOp handle non-255 weights.

This fixes the bug where this brush slowly outputs everything to transparent.

The bug was caused by the fact that to sample the input pixels, the crossdevice
color picker was used, which in turn got access to subpixel data by utilizing
the randomsubaccessor, which was getting that data by mixing neighbouring pixels
via the KoColorMixOp. However, the randomsubaccessor isn't able to generate
perfect sums-to-255 weights every single time, meaning transparency was added.

This commit fixes that by making the weights in KoColorMixOp always use the sum
of the weights as the normalization factor.

Special thanks to Dmitry for figuring this out.

M  +8    -4    libs/pigment/KoMixColorsOpImpl.h

https://invent.kde.org/graphics/krita/commit/15b1ebf076f476b399161d5928419b7be106c568
Comment 15 wolthera 2020-07-24 21:54:06 UTC
Git commit 5101cddfdd340d47503801944c6dfe7906bf088e by Wolthera van Hövell.
Committed on 24/07/2020 at 21:54.
Pushed by woltherav into branch 'master'.

This fixes the bug where this brush slowly outputs everything to transparent.

The bug was caused by the fact that to sample the input pixels, the crossdevice color picker was used, which in turn got access to subpixel data by utilizing the randomsubaccessor, which was getting that data by mixing neighbouring pixels via the KoColorMixOp. However, the randomsubaccessor isn't able to generate perfect sums-to-255 weights every single time, meaning transparency was added.

This commit fixes that by passing a sum of weights to the KoColorMixOp that only defaults to 255.

Special thanks to Dmitry for figuring this out.

Note: there's still an issue with colors mixing darker in 8bit, we're still trying to figure that one out. But at the least there's no transparency.

M  +14   -2    libs/image/kis_random_sub_accessor.cpp
M  +8    -5    libs/pigment/KoMixColorsOp.h
M  +8    -7    libs/pigment/KoMixColorsOpImpl.h

https://invent.kde.org/graphics/krita/commit/5101cddfdd340d47503801944c6dfe7906bf088e
Comment 16 wolthera 2020-07-24 21:56:20 UTC
Git commit 30cb1e7106dd3cc272fc68e4478fd136e2e6e204 by Wolthera van Hövell tot Westerflier, on behalf of Wolthera van Hövell.
Committed on 24/07/2020 at 21:56.
Pushed by woltherav into branch 'krita/4.3'.

This fixes the bug where this brush slowly outputs everything to transparent.

The bug was caused by the fact that to sample the input pixels, the crossdevice color picker was used, which in turn got access to subpixel data by utilizing the randomsubaccessor, which was getting that data by mixing neighbouring pixels via the KoColorMixOp. However, the randomsubaccessor isn't able to generate perfect sums-to-255 weights every single time, meaning transparency was added.

This commit fixes that by passing a sum of weights to the KoColorMixOp that only defaults to 255.

Special thanks to Dmitry for figuring this out.

Note: there's still an issue with colors mixing darker in 8bit, we're still trying to figure that one out. But at the least there's no transparency.

M  +14   -2    libs/image/kis_random_sub_accessor.cpp
M  +8    -5    libs/pigment/KoMixColorsOp.h
M  +8    -7    libs/pigment/KoMixColorsOpImpl.h

https://invent.kde.org/graphics/krita/commit/30cb1e7106dd3cc272fc68e4478fd136e2e6e204
Comment 17 SirPigeonz 2020-07-24 21:57:54 UTC
WOW Dimitri, Wolthera, you guys are amazing, thank you!
Comment 18 wolthera 2020-07-24 22:03:31 UTC
Ah, before you heap endless praise on us, as the messages state, there's still a problem within 8bit spaces, the colors avarage towards being dark (with green-red mix ending up black). The two possibilities here is either to use the precisepaintdevice wrapper as we're doing with the colorsmudge (this however requires a bit of refactor and makes the brush noticebly slower), or we're going to try and fix the kocolormixop further.
Comment 19 SirPigeonz 2020-07-25 10:00:12 UTC
Yup! I've read about color shifts but it is still great improvement for me! It will allow me to use this tool where I couldn't before! :D

When you fix color shifts it will expand use cases even more. But this fix is huge even as it is now thank you!
Comment 20 wolthera 2020-07-25 10:54:36 UTC
Git commit f0a9a2e7051a4f5ee213413ec5e7492ed7a11923 by Wolthera van Hövell tot Westerflier.
Committed on 25/07/2020 at 10:54.
Pushed by woltherav into branch 'master'.

Fix darkening of colors using the deform brush.

Based of dmitry's initial patch, this adds a hack to ensure
the appropriate division function is selected. We should be using
KoColorSpaceMaths and templates for this, but it is not clear to me
how this should be done, and I even suspect it requires a bigger refactor.

This however is fast enough and makes the brush work as expected in 8bit
integer and 32bit float versions of all the available color models.

M  +14   -2    libs/pigment/KoMixColorsOpImpl.h

https://invent.kde.org/graphics/krita/commit/f0a9a2e7051a4f5ee213413ec5e7492ed7a11923
Comment 21 wolthera 2020-07-25 10:55:26 UTC
Git commit e49da79a64ab02e6cf6db92f051c408b383748fc by Wolthera van Hövell tot Westerflier.
Committed on 25/07/2020 at 10:55.
Pushed by woltherav into branch 'krita/4.3'.

Fix darkening of colors using the deform brush.

Based of dmitry's initial patch, this adds a hack to ensure
the appropriate division function is selected. We should be using
KoColorSpaceMaths and templates for this, but it is not clear to me
how this should be done, and I even suspect it requires a bigger refactor.

This however is fast enough and makes the brush work as expected in 8bit
integer and 32bit float versions of all the available color models.

M  +14   -2    libs/pigment/KoMixColorsOpImpl.h

https://invent.kde.org/graphics/krita/commit/e49da79a64ab02e6cf6db92f051c408b383748fc
Comment 22 Dmitry Kazakov 2020-07-27 09:33:28 UTC
Git commit 3967105ce4532bd8d7955566f5144bd336c5d414 by Dmitry Kazakov.
Committed on 27/07/2020 at 09:32.
Pushed by dkazakov into branch 'master'.

Refactor rounded division hack in KoMixColorsOpImpl to use templates

M  +20   -10   libs/pigment/KoMixColorsOpImpl.h

https://invent.kde.org/graphics/krita/commit/3967105ce4532bd8d7955566f5144bd336c5d414
Comment 23 Dmitry Kazakov 2020-07-27 10:36:46 UTC
Git commit ea04b8afef1631adcff5377653c154124909c2d2 by Dmitry Kazakov.
Committed on 27/07/2020 at 10:36.
Pushed by dkazakov into branch 'krita/4.3'.

Refactor rounded division hack in KoMixColorsOpImpl to use templates

M  +20   -10   libs/pigment/KoMixColorsOpImpl.h

https://invent.kde.org/graphics/krita/commit/ea04b8afef1631adcff5377653c154124909c2d2