![]() Registered Member ![]()
|
One thing I've noticed when shading is, if I do all of the shading with a single brush stroke and a hard-edged brush, it tends to look very natural and have a smooth progression of color/alpha/value/etc while retaining the appearance of the strokes used to shade it. However, if I shade with multiple strokes, I'll often get bands of darker or lighter canvas where either I've overlapped with the previous stroke or left a gap.
![]() I think this is because Krita builds the stroke as you draw, and when you release the stroke it composites that entire thing down to the canvas. So if I e.g. reverse stroke back over an area that I've already covered in that stroke, it only updates the values there if the pressure I'm using is higher (e.g. if the stroke is more opaque). I was trying to figure out if there was some way to produce that behavior in general using the various blending modes, but I haven't found anything that quite behaves in that fashion. I think its pretty easy to specify the pseudocode though; something like:
This might give some harsh lines if you change colors between uses, so maybe some sort of sigmoidal suppression:
The larger 'constant' is, the sharper the transition line between the new stroke having to have a higher alpha than what's already on the layer to come through. This seems like a simple enough thing to try, but I can't find much documentation about implementing new blending modes or writing Krita plugins in general. |
![]() KDE Developer ![]()
|
Hi,
The code for blending modes is in libs/pigment/compositeops. Blending modes are fairly easy to write, so it should be quite doable to experiment there. You might also want to experiment with the difference between the build-up and the wash mode. |
![]() Registered Member ![]()
|
Thanks for that, I've now been able to create a new blend mode that works for greyscale. Something weird happens with color though - it appears to convert whatever was underneath it into greyscale.
I used the Behind blend mode as a template, and replaced the core of the loop with:
|
![]() KDE Developer ![]()
|
Well... If the destination paint device is grayscale, then src will be converted -- or isn't that what you mean? In any case, if you get this working, don't hesitate to submit a patch
![]() |
![]() Registered Member ![]()
|
Alright, I managed to fix the greyscale thing - it had something to do with dividing by the new opacity. I'm not actually sure about what the channel_type variable ranges are (0..1 or 0..255) so I tried to normalize by unitValue. There's still something weird where the new hue immediately shifts to whatever you're drawing with instead of the old color, so my guess is that my code for updating each channel is still a bit messed up, but the code for determining the overall new alpha value is fine (that would give the observed behavior).
Current status: ![]() I made a patch file for this version since it does work perfectly fine for drawing with the same color at least; I should say though, this'll be the first time using Git for me, so I apologize for anything I've messed up in constructing this: http://www.urbanhermitgames.com/greaterblend.patch |
![]() Registered Member ![]()
|
Okay, I think I've managed to fix it and improve the blending a bit. Now it works properly for different colors and doesn't have the weird banding you could sometimes get.
http://www.urbanhermitgames.com/greaterblend2.patch |
![]() KDE Developer ![]()
|
Looks good! I'll test it today and if all is well, push it to master!
|
![]() KDE Developer ![]()
|
Hm... I get two weird results:
* the blending mode doesn't work on the non-transparent default bottom layer * when using a mouse instead of a tablet, the edges of overlapping strokes are white (Both are logical, I guess, but surprising when using the blending mode) |
![]() Registered Member ![]()
|
The bottom layer thing is because the alpha of that layer is already at maximum, which as you say is 'logical but surprising'. Can you think of a way to make it seem more natural without actually changing the intended function of the mode to be a 'greater than' operation on the alpha? Maybe re-classifying the blend mode into a different category would be appropriate (there's always 'Misc' of course, but that's not very helpful).
The white edges are kind of surprising to me, and I'm not sure why that's happening. I think I may not be understanding how Krita actually stores colors internally, and that may be part of it. When I wrote the blend mode, this was my thought: The image contains three channels storing colors (r,g,b or c,m,y or whatever) and one channel storing alpha (a). When you paint with a brush of color (r0,g0,b0) and opacity 'o' onto a blank section of transparent layer, the new value there will be (r0,g0,b0, o*pressure_alpha*brush ). Instead though, it seems as though the color channels are also not constant, so you get something like (r0*pressure_alpha*brush,g0*pressure_alpha*brush,b0*pressure_alpha*brush,o*pressure_alpha*brush), even when you set dst[channel] = src[channel]. Is that true? If so, then it seems like to remove the white edges I'd need to actually go one step up in the compisiting code to change where it's post-multiplying the destination color values by the total alpha. Or I need to divide out the alpha somehow while still making sure that values stay within the range allowed by channels_type (I suspect this won't work for anything but 32bit float layers) Edit: Here's a patch which appears (for me) to fix the white edges on the mouse. There's a small problem now with drawing strokes of very different hues but at nearly the same pressure, where those now have white edges (due to red+cyan = grey type math). However I think this is probably less disruptive since its not such a 'sharp' feature. http://www.urbanhermitgames.com/greaterblend3.patch |
Registered users: bancha, Bing [Bot], Evergrowing, Google [Bot], Sogou [Bot]