Wash mode like in krita for brushes

brush_engine
Tags: #<Tag:0x00007f14c92db7b8>

#1

I find wash mode much more comfortable when painting, it’s easier to control the value of your stroke because it’s uniform as long as you keep the same pressure. Although this only applies to brushes with transparency and specific strokes that overlap themselves.

Just to visualize what I’m after, here’s what the difference looks like in krita. Above is buildup - similar to mypaint behavior, below is wash mode:


#2

edit I just tried krita on my laptop and realized this is the default setting and has nothing to do with opaque guache :slight_smile:
My brain really hurts now trying to figure out what flow vs opacity is in Krita. A 100% opaque brush is still transparent with flow on? Ahhhhh :slight_smile:

I’m wondering if this might be somewhat what you’re looking for:

Basically create a 100% opaque brush, then control smudge with pressure and turn smudge-lock on.

The caveat is that smudge only grabs the color from the current layer, not any layers below. I think that’s because it’s meant to emulate mixing the paint with the current layer’s paint


#3

Not really what i’m looking for, but thanks. I don’t want it to be a smudge brush, the smudge brushes are useful to me as they are.


#4

Yeah the more I played with Wash mode the more it seemed quite different than smudge locking. They both lock something at the beginning of the stroke, but that seems to be the only similarity.

It almost seems like Krita is making a new layer at the beginning of the stroke, and at the end of the stroke it merges it. But it’s more complicated than that since within the stroke it doesn’t remix with itself. It also ratchets towards more opaque-- the stroke won’t get LESS opaque once it is drawn. Not sure how it’s doing that.

It seems really cool… it MIGHT be possible with new code but yeah, not going to happen soon :frowning:


#5

It almost seems like Krita is making a new layer at the beginning of the stroke, and at the end of the stroke it merges it.

AFAIK that is exactly right (functionally – internally it’s probably more optimized than making a whole new layer)
GIMP does the same thing (except for Mypaint-Brush tool, I think?)

It’s like making a new layer and setting its opacity to the brush opacity. Brush is then applied in the ‘normal’ fashion (ie. like Normal mode).
If you look at GIMP, it also has another setting ‘Force’ which IIRC is analogous to ‘Flow’ in Photoshop : it controls the opacity with which the brush is applied to the buffer. Low force == airbrushy buildup, High force == near instant buildup.

But it’s more complicated than that since within the stroke it doesn’t remix with itself. It also ratchets towards more opaque-- the stroke won’t get LESS opaque once it is drawn. Not sure how it’s doing that.

It does remix though; that’s normal behaviour that MyPaint already exhibits (applying dabs only reduces opacity of pixels if you are using Erase or Smudge; applying dabs that have lower opacity just adds less opacity at once.)

Smudge is kind of a corner case here.

If you turn this whole thing inside-out, you could say instead that MyPaint’s method is like each individual dab is one application of Wash. Since the application area is much smaller in MyPaint’s method, it’s more optimisable.

IMO MyPaint’s expectations WRT the behaviour of Smudge is the biggest stumbling block. I’m not sure what the correct behaviour for Smudge sampling is, but I suspect we cannot make it give just the same results with Wash application mode.

EDIT: GIMP’s handling of Smudge avoids this problem by making smudging entirely Mypaint-style (not wash). Since in MyPaint smudging is not a binary thing, we probably cannot directly adopt such a straightforward approach.


#6

Thanks for the more detailed information! I think it’s fascinating how different programs approach problems slightly differently, but I don’t have time to dig into the code to examine everything :slight_smile:

You’re right, it won’t get less opaque (not sure what I was thinking there) but it Wash mode doesn’t seem to add more opacity to a pixel unless the brush opacity is MORE than the pixel’s opacity.

Not quite sure I follow-- the layer itself can’t be set to the brush opacity when the brush opacity is being controlled by pressure, right?
So, we definitely have a new layer, but there seems to be logic that happens during the blending of two pixels so that the resulting pixel opacity is never MORE than the brush opacity (or the canvas opacity). Maybe there is no “blending” of the opacity at all, it just compares the two and assigns the greater opacity value? Maybe we just need a new Paint Mode called “Ratchet Opacity” haha


#7

I was playing with brushmodes and trying to implement something like lock alpha but instead do MAX alpha but it was horribly broken and obviously much more complicated than I thought.


#8

Sorry, I meant the base brush opacity. In the GIMP model, dynamic variation in brush opacity is equivalent to multiplying flow * dyn_opacity (if you assume these are both in the range [0…1] )

Wash mode doesn’t seem to add more opacity to a pixel unless the brush opacity is MORE than the pixel’s opacity

Hmm. Now I’m not sure. I’d want to check the code. In principle I understand why you would make that choice, I just don’t remember it actually happening.


#9

I stumbled on this issue and it seems directly related, Martin mentions MAX opacity and the temporary layer:

I think part of the difficulty is because brushlib by design works by blending faint dabs on top of each other. The interaction of individual dabs creates an alpha fall-off at the stroke border that is very hard to predict because it depends on too many non-constant parameters (radius, dab density, opacity, elliptical ratio).

(This is in contrast to a design with a temporary stroke layer, where individual dabs have their alpha-channels MAX’ed instead of OVER-blended. MAX’ing creates a very predictable alpha fall-off. But it also creates an unnatural change in the stroke’s self-overlap whenever the layer is merged down.