Re: [Gimp-developer] Airbrush/Brush Banding Effect At Low Pressure/Opacity

2009-11-21 Thread Martin Renold
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

2009-11-18 Thread David Gowers
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

2009-11-18 Thread James Cox
> 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

2009-11-18 Thread Christopher Howard

-- 
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

2009-10-21 Thread Jay Cox

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

2009-10-20 Thread Sven Neumann
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

2009-10-20 Thread Christopher Howard

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