Re: [Gimp-developer] Airbrush/Brush Banding Effect At Low Pressure/Opacity
On Thu, Nov 19, 2009 at 02:01:13PM +1030, David Gowers wrote: > On Thu, Nov 19, 2009 at 11:17 AM, James Cox wrote: > > result = floor(input * opacity + g_random_double()); > > If you pregenerate a lookup table (say 256 entries), keep a counter > which cycles 0,1,2,255,0,1,2,255, and only add a random > integer to that counter at the start of every dab, you could get that > going at decent speeds. I have implemented this in (historical) release 0.5.1 of MyPaint. Using 8 bytes of precalculated noise; brush_dab.c line 120 in case anyone cares. I got sick of the noise, though. It tends to get visible when you use brushes that really need this correction. Not worth the effort I think. The better solution is to calculate in 16bpc, or use different brushes, or don't use incremental mode (MyPaint supports only incremental). See http://mypaint.intilinux.com/?p=19 for a sample. ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
Re: [Gimp-developer] Airbrush/Brush Banding Effect At Low Pressure/Opacity
On Thu, Nov 19, 2009 at 11:17 AM, James Cox wrote: >> Christopher Howard wrote: > Thinking about this some more, the error diffusion is probably not even > necessary. You should be able to get by with some random dithering like > the following (if it wasn't slower than molasses): > > result = floor(input * opacity + g_random_double()); If you pregenerate a lookup table (say 256 entries), keep a counter which cycles 0,1,2,255,0,1,2,255, and only add a random integer to that counter at the start of every dab, you could get that going at decent speeds. ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
Re: [Gimp-developer] Airbrush/Brush Banding Effect At Low Pressure/Opacity
> Christopher Howard wrote: >> Jay Cox wrote: >> >> On Oct 20, 2009, at 1:39 PM, Sven Neumann wrote: >> >>> Hi, >>> >>> On Tue, 2009-10-20 at 12:22 -0800, Christopher Howard wrote: >>> Though having a far from sufficient understanding of how the GIMP brush painting process works, it seems to me like this is the fundamental problem: In making black-and-white brushes semi-transparent, GIMP somehow "levels out" the grey-scale, so that certain ranges of darkness become the same. On a fuzzy brush, the result is that the fine graduation is changed to appear stepped or banded. >>> >>> The problem here is that the brush masks are 8bit only. With such a >>> limited set of values to start with, banding is basically unavoidable. >>> >>> >>> Sven >> >> You should be able to get rid of most of the banding by performing error >> diffusion when multiplying the opacity into the brush mask. I suspect >> that a simple 1d error diffusion algorithm will be sufficient and I >> wouldn't bother with a Floyd-Steinberg type algorithm unless you could >> come up with an example where the simpler algorithm showed visible >> artifacts. >> >> I believe the function that introduces the banding is >> apply_mask_to_sub_region in paint-funcs.c or in the function >> apply_mask_to_alpha_channel depending on your point of view. I have not >> worked with that code in a long time and I could be wrong about that. >> >> You will need to make the starting error term effectively random or you >> run the risk of letting the upper-left pixel in each tile get special >> treatment. >> >> Good luck, >> Jay Cox >> jay...@gimp.org > >Thank you for your guidance in this matter. However, I am wondering: >Wouldn't error diffusion tend to sharpen, rather than smooth out, the >banding? It seems like some kind of blurring is more what we need. > >I played around in apply_mask_to_alpha_channel() a little bit and my >results seemed to confirm that. But maybe I misunderstand error >diffusion or precisely what you mean about how to use it? Error diffusion will get rid of banding at the cost of a small amount of noise. If you paint with the same error diffused mask multiple times you will amplify the noise. Blurring the mask can not help. An Example: The input mask is a smooth gradient from 0 to 10 that we are scaling to 10% current scaling: 0 0 0 0 0 1 1 1 1 1 current painted 10X in the same location: 0 0 0 0 0 10 10 10 10 10 Obviously that leaves a hard break between the 5th and 6th value. Note that if we blurred the resulting mask we would end up with the exact same values. Error diffusion (static): 0 0 0 1 0 1 0 1 1 1 Error diffusion (static) painted 10X in the same location: 0 0 0 10 0 10 0 10 10 10 It looks like we have even more banding, though it would likely look like noise in a real image. Error diffusion with a random initial error term: 0 0 0 1 0 1 0 1 1 1 or 0 1 0 0 1 0 1 0 1 1 or 0 0 1 0 0 1 0 1 0 1 or .. Error diffusion with a random initial error term painted 10X in the same location: 0 1 2 3 4 5 6 7 8 9 10 or 0 1 3 3 4 5 6 7 7 9 9 or .. The results are not mathematically perfect, but should look very good visually. If you are initializing the error term to a random value and still seeing banding I would suspect that the brush system is caching the results of your function and applying the same mask over again. (simple way to check is to put a printf statement in your function and check to see if it prints out every time you click with the paintbrush) Thinking about this some more, the error diffusion is probably not even necessary. You should be able to get by with some random dithering like the following (if it wasn't slower than molasses): result = floor(input * opacity + g_random_double()); Jay Cox jay...@gimp.org PS: If this message came through twice I apologize. The other one (if it exists) contains errors (more errors?) and should be ignored. ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
Re: [Gimp-developer] Airbrush/Brush Banding Effect At Low Pressure/Opacity
-- Christopher Howard http://indicium.us http://theologia.indicium.us --- Begin Message --- -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Jay Cox wrote: > > On Oct 20, 2009, at 1:39 PM, Sven Neumann wrote: > >> Hi, >> >> On Tue, 2009-10-20 at 12:22 -0800, Christopher Howard wrote: >> >>> Though having a far from sufficient understanding of how the GIMP brush >>> painting process works, it seems to me like this is the fundamental >>> problem: In making black-and-white brushes semi-transparent, GIMP >>> somehow "levels out" the grey-scale, so that certain ranges of darkness >>> become the same. On a fuzzy brush, the result is that the fine >>> graduation is changed to appear stepped or banded. >> >> The problem here is that the brush masks are 8bit only. With such a >> limited set of values to start with, banding is basically unavoidable. >> >> >> Sven > > You should be able to get rid of most of the banding by performing error > diffusion when multiplying the opacity into the brush mask. I suspect > that a simple 1d error diffusion algorithm will be sufficient and I > wouldn't bother with a Floyd-Steinberg type algorithm unless you could > come up with an example where the simpler algorithm showed visible > artifacts. > > I believe the function that introduces the banding is > apply_mask_to_sub_region in paint-funcs.c or in the function > apply_mask_to_alpha_channel depending on your point of view. I have not > worked with that code in a long time and I could be wrong about that. > > You will need to make the starting error term effectively random or you > run the risk of letting the upper-left pixel in each tile get special > treatment. > > Good luck, > Jay Cox > jay...@gimp.org Thank you for your guidance in this matter. However, I am wondering: Wouldn't error diffusion tend to sharpen, rather than smooth out, the banding? It seems like some kind of blurring is more what we need. I played around in apply_mask_to_alpha_channel() a little bit and my results seemed to confirm that. But maybe I misunderstand error diffusion or precisely what you mean about how to use it? - -- Christopher Howard http://indicium.us http://theologia.indicium.us -BEGIN PGP SIGNATURE- Version: GnuPG v2.0.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAksEcwwACgkQQ5FLNdi0BcWKRQCfct8rNIrRpQ9Rr6h1l7AQE1ft 9KEAn1KyfNh66uNVFpmF301gJI4zQ4tn =/vnh -END PGP SIGNATURE- - To unsubscribe, send email to with 'unsubscribe' in the message body. --- End Message --- signature.asc Description: OpenPGP digital signature ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
Re: [Gimp-developer] Airbrush/Brush Banding Effect At Low Pressure/Opacity
On Oct 20, 2009, at 1:39 PM, Sven Neumann wrote: > Hi, > > On Tue, 2009-10-20 at 12:22 -0800, Christopher Howard wrote: > >> Though having a far from sufficient understanding of how the GIMP >> brush >> painting process works, it seems to me like this is the fundamental >> problem: In making black-and-white brushes semi-transparent, GIMP >> somehow "levels out" the grey-scale, so that certain ranges of >> darkness >> become the same. On a fuzzy brush, the result is that the fine >> graduation is changed to appear stepped or banded. > > The problem here is that the brush masks are 8bit only. With such a > limited set of values to start with, banding is basically unavoidable. > > > Sven You should be able to get rid of most of the banding by performing error diffusion when multiplying the opacity into the brush mask. I suspect that a simple 1d error diffusion algorithm will be sufficient and I wouldn't bother with a Floyd-Steinberg type algorithm unless you could come up with an example where the simpler algorithm showed visible artifacts. I believe the function that introduces the banding is apply_mask_to_sub_region in paint-funcs.c or in the function apply_mask_to_alpha_channel depending on your point of view. I have not worked with that code in a long time and I could be wrong about that. You will need to make the starting error term effectively random or you run the risk of letting the upper-left pixel in each tile get special treatment. Good luck, Jay Cox jay...@gimp.org ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
Re: [Gimp-developer] Airbrush/Brush Banding Effect At Low Pressure/Opacity
Hi, On Tue, 2009-10-20 at 12:22 -0800, Christopher Howard wrote: > Though having a far from sufficient understanding of how the GIMP brush > painting process works, it seems to me like this is the fundamental > problem: In making black-and-white brushes semi-transparent, GIMP > somehow "levels out" the grey-scale, so that certain ranges of darkness > become the same. On a fuzzy brush, the result is that the fine > graduation is changed to appear stepped or banded. The problem here is that the brush masks are 8bit only. With such a limited set of values to start with, banding is basically unavoidable. Sven ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
[Gimp-developer] Airbrush/Brush Banding Effect At Low Pressure/Opacity
Hi. To try to learn GIMP development, I have been looking into old bug #588681 (Airbrush tool produces banding with with soft brush). From the initial problem summary: "The Airbrush produces bandings when its used with a soft brush and low pressure. The sharp edges in the bands is [sic] very visible when it occurs in a otherwise soft image. The low pressure is very useful when I want to have good control over the spray." He uploaded an image as well of the effect, which I can easily reproduce. When using the airbrush, the severity of the effect is indirectly proportional to the pressure level selected. The exact same problem can be reproduced with a normal fuzzy brush, simply by selecting a low opacity, and repeatedly clicking on the canvas in the same location. Initially I spent a lot of time looking at app/core/gimpbrushgenerated.c, and especially gauss(), gimp_brush_generated_calc_lut(), and gimp_brush_generated_calc(). This is because I mistakenly supposed that the problem lay in the construction of the lookup table used initially to create the brush mask. However I discovered that this is completely unaffected by the brush opacity or airbrush pressure. Though having a far from sufficient understanding of how the GIMP brush painting process works, it seems to me like this is the fundamental problem: In making black-and-white brushes semi-transparent, GIMP somehow "levels out" the grey-scale, so that certain ranges of darkness become the same. On a fuzzy brush, the result is that the fine graduation is changed to appear stepped or banded. I would appreciate any insight into this matter. I have started to look into how brushes are made (applied?) semi-transparent in the code, but there are quite a few functions in the paint-funcs directory to look through. -- Christopher Howard http://indicium.us http://theologia.indicium.us signature.asc Description: OpenPGP digital signature ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer