Coder Social home page Coder Social logo

Brush Setting: Offset about libmypaint HOT 38 CLOSED

AnTi-ArT avatar AnTi-ArT commented on June 14, 2024
Brush Setting: Offset

from libmypaint.

Comments (38)

rbreu avatar rbreu commented on June 14, 2024 1

I just updated my branch with a lower boundary for the vector norm calculation. As I don't get any jitter myself, I chose a value that was smaller than anything I got during normal usage, hoping that it helps.

from libmypaint.

rbreu avatar rbreu commented on June 14, 2024 1

I do remember, yes!, and I really appreciate your work. I don't have much time right now, but I can't wait to try this myself some time.

from libmypaint.

martinxyz avatar martinxyz commented on June 14, 2024

The problem with a rake brush is that the outer part of a turn-around needs more dabs than the inner part. But the offset you describe should be very easy to implement (something like 8 lines of code). Instead of X/Y use Offset_Angle/Offset_Distance, then you can map it to the "stroke direction" inputs.

from libmypaint.

martinxyz avatar martinxyz commented on June 14, 2024

Old forum thread: http://forum.intilinux.com/mypaint-development-and-suggestions/suggestion-%27offset%27-parameter-for-paint-dabs/

from libmypaint.

AnTi-ArT avatar AnTi-ArT commented on June 14, 2024

Ah, that's cool. Now if I could just teach scons to find it's own install path, I could actually compile the git version manually :| (edit: I got it, it compiles and runs, now I can try stuff)
I'd like to test this. And an offset setting with x and y. Like this?
mypaint-brush.c line 640

if (self->settings_value[MYPAINT_BRUSH_SETTING_OFFSET_Y]) {
  y += self->settings_value[MYPAINT_BRUSH_SETTING_OFFSET_Y] * base_radius;
}
if (self->settings_value[MYPAINT_BRUSH_SETTING_OFFSET_X]) {
  x += self->settings_value[MYPAINT_BRUSH_SETTING_OFFSET_X] * base_radius;
}

I feel that the angled approach has a drawback: It is harder to make an offset, that does not follow the stroke (a simple "move", like x-y-offset). Well, this needs experimentation...

Mh, the dabs amount is probably not that critical for a basic implementation. The 4-line brush I made with offset by speed looks good enough.

Edit 2: I looked at your Offset by Direction Code. You alternate between both sides automatically. I'd let the user do the "sorting". e.g if you want a brush with 2 strokes, you just need half the dabs offset to one side of the original, the other half can stay...

from libmypaint.

AnTi-ArT avatar AnTi-ArT commented on June 14, 2024

offsets
This was so easy I almost fainted.
However I just noticed that Direction is 0 to 180 only, no difference between left-vs-right. This makes it a lot harder to turn x-y-offset into angular offset using a sinecurvey Direction input:
offset2
I assumed direction was 360°. Why not? It doesn't matter for rotation of elliptic dabs, but everything else seems not logical with the "hard brakes"... Maybe it's best to add both variants and a new "Offset" category for myPaint, that includes: Jitter, X&Y Offset, Angular Offset, Offset by Speed and it's Filter. some more brush experiments

from libmypaint.

martinxyz avatar martinxyz commented on June 14, 2024

180° vs 360° direction matters for elliptic dabs, because of the in-between angles you need to go through when you change direction:

direction-input-180

Of course, when you want to use the "direction" input for something else, it may be better to have it go full-circle. But I think that would need a second "direction" input, leaving the unaware brush-designer completely puzzled about which one to choose.

from libmypaint.

martinxyz avatar martinxyz commented on June 14, 2024

Sorry, hit the "close and comment" button by accident.

from libmypaint.

AnTi-ArT avatar AnTi-ArT commented on June 14, 2024

Yes, I see that's ugly. Maybe it's possible to use 180 for dab orientation only, and all other settings get the full 360?

Anyway, I tried some more stuff (I made my first fork!): The offset to both sides you posted. Obviously it's a lot more even then separating the dabs "manually", and it's possible to use a 0 minimum (offset to one side is -20 to 20), I guess that's why additional modification works a lot better (like pressure):
offset4
Downside is, that one cannot easily tread both lines separately, like giving them different colors, or a different amount of dabs...

from libmypaint.

martinxyz avatar martinxyz commented on June 14, 2024

Before doing a sneaky special-case for the "elliptical dab angle" direction input, I think we should simply add the required direction_360 input, and start thinking about hiding some inputs by default in the user interface.

from libmypaint.

martinxyz avatar martinxyz commented on June 14, 2024

And I quickly glanced over your fork: in case you plan to make a pull request later, you should replace the "static int" (which was an easy hack for brainstorming) with a proper new state in brushsettings.json, even if it toggles only between 0 and 1.

from libmypaint.

AnTi-ArT avatar AnTi-ArT commented on June 14, 2024

I guess, I'd rather make a clean fork (or something like this) before ever doing a pull request, I have now a lot of experimentation in this one. I added 360 direction now, and of course nothing works like I imagined in the beginning :) 1. The ccw/cw of 360 input depends of the strokes ccw/cw direction anyway. 2. Turning the x-y-offset into an offset that runs alongside the stroke does work for all dabs only, no way to split them with random or strokes. This would need input chains like "take half of the dabs and only offset those"...
Anyway, one can still do some psychedelic mad brushes!
offset-test-1

from libmypaint.

achadwick avatar achadwick commented on June 14, 2024

I notice that the Windows unofficial builds are already including this.

@AnTi-ArT is this ready? Please can you submit a PR if it is, just to make it easier to review?

from libmypaint.

LeniaLDZ avatar LeniaLDZ commented on June 14, 2024

Hi, is work still being done on this? I see great potential in it, having a proper rake brush in Mypaint - that's why I asked Tumagonx to include it in the windows build so I could experiment with it. Using it, it's possible to create not only rakes but more realistic textured markers/chalks. Here's an example:
11-kept-in-e
I absolutely love this feature and would love to help with it's development, sadly I'm a noob at coding mypaint. Is it possible to offset more than one stoke on either side without having to split the dabs and thus create gaps in the strokes? To get, say, a rake with 4 solid teeth?

from libmypaint.

achadwick avatar achadwick commented on June 14, 2024

@tumagonx - what's the testing verdict on this one? Results are looking pretty sweet.

I'll need to know the location of the branch so I can pull it and check it out. @AnTi-ArT : is it just your master on https://github.com/AnTi-ArT/libmypaint ?

from libmypaint.

LeniaLDZ avatar LeniaLDZ commented on June 14, 2024

@achadwick - testingwise, the feature as it is works ok, at least on windows. I see even greater potential in it though as I said. The brushes I used in this pic were made with the settings from @AnTi-ArT 's last update 7 months ago. I personally only edited the brushsettings.json so I could increase the maximum number of dabs per actual radius for some brushes.

from libmypaint.

rbreu avatar rbreu commented on June 14, 2024

What is the status of this? I have managed to pull the changes into an up-to-date branch and play around with it. You can get a couple of nice effects with it in combination with smugde:

test1
test2

I cannot seem to get the "rake lines" generated by this to be proper lines though, no matter how hig the amount of dabs; dabs are still visible as dots if you look closely, which is especially visible when you don't use smuge. I haven't looked into the code yet, maybe it's because the dab density spreads across all "rake lines"? Or maybe it's me, since I'm not sure I understand all brush settings yet. But even as is I find the results a nice start to having something more akin to bristle brushes.

I could do a pull request from my branch if @AnTi-ArT is MIA, though I'm not keen on taking the credit for it.

from libmypaint.

briend avatar briend commented on June 14, 2024

I think @LeniaLDZ bumped up max dabs for that reason, to get a more solid rake effect. There actually is a pull request for this already. I think it just takes time. There are many bugs @achadwick and others are busy squashing. Beautiful drawing BTW :-)

from libmypaint.

rbreu avatar rbreu commented on June 14, 2024

Ha, I completely ovelooked that PR! Great! And now I suddenly understand what @LeniaLDZ meant with max dabs, seems like just the thing I need to tweak. Will play around with it some more during the weekend and maybe do a more thorough painting as well.

It'll also be interesting to see what other effects people will get out of it.

from libmypaint.

briend avatar briend commented on June 14, 2024

Yeah I want to test that out too. I'm guessing if we bump up max dabs (both settings) to like 10x or 100x what it is now that might be plenty. I'm sure there would be a huge performance penalty but there are plenty of other settings that can kill your computer as it is now.

Maybe we need another set of definitions... reasonable_min and reasonable_max... and the GUI can turn red when you go beyond those as a warning. I'm sure I'm not the only to wait 2 minutes while mypaint catches up with a crazy brush setting

from libmypaint.

rbreu avatar rbreu commented on June 14, 2024

Huh, changing the dabs per radius (either actual or basic radius) does not what I expected (this is all with the "Angular Offset Mirrored" setting):
rake_test

And the stroke setting affects the number of rake lines, which is also not quite intuitive? Or is it just me?
rake_test2

from libmypaint.

briend avatar briend commented on June 14, 2024

The stroke makes sense if you have a really short duration and thresh-hold it is basically always going from 0.0 thru 1.0 really fast. So square steps will create rakes and angles will create a distribution of points.

BUT. There is something totally weird going on with the relationship between brush dabs (all three, basic, actual, and seconds), radius, and the Angular Offset. In order to get a rake brush with really solid lines I actually had to bump the angular offset mirrored range up to 4000 (from 40) and increase dabs per basic radius to 50, and use a really tiny brush radius -0.5. It's like as soon as you adjust one of these three, the others get out of wack and need huge shifts to compensate for something.

This weird behavior doesn't affect the normal X/Y offset, so I'm pretty sure it has something to do with the way direction is calculated, and even time. I'll have to make a video but basically it's really weird.

from libmypaint.

rbreu avatar rbreu commented on June 14, 2024

Ah, okay, I finally made the connection between all the stroke settings and what they mean. I can now make earthworm brushes and squares-on-a-string brushes. :D

offset_stroke_test

I'll try to understand the code re dabs, radius and angle. That really is strange.

from libmypaint.

rbreu avatar rbreu commented on June 14, 2024

I have to admit I still don't understand what exactly MYPAINT_BRUSH_STATE_DIRECTION_DX and DY are, but from the angular offset code it seems clear that it's a vector pointing in the direction we want (i.e. perpendicular to the stroke direction) but with a length not quite suitable. So I thought we could just use its direction info as a base for the calculation by dividing the components by its norm, ignoring the length since we get that from the offset setting and the brush radius. Here's the code change for that and here my branch with the changes. This keeps the width of the "rake" independent from dabs, just makes it adjustable with the radius. Note that with this change, you'll need much smaller values of the angular offset than before.

I still can't get solid lines, though, at least not for a rake with 6 or 8 lines. No matter how big I set the amount of dabs, after some point it seems to just redraw some of the dabs onto existing dabs instead of into the spaces between. Interestingly enough, the slowdown I get with huuuge amount of dabs is worse with a smaller brush radius than with a bigger brush radius. It's all very confusing.

from libmypaint.

martinxyz avatar martinxyz commented on June 14, 2024

The (theoretical) problem with dividing by norm_d in 0f038fe is that you may divide by zero or something very close. This amplifies noise, like some tiny shaking you can't really control, or when changing direction at just the wrong angle. At least enforce a minimum value for norm_d before you divide by it; the minimum should probably be a fraction of the brush's basic radius.

About the slow-down with smaller dabs, this makes sense because the math of placing individual dabs (all the exp and hypot and updating) is quite expensive for a large number of tiny dabs.

Maybe I'll find time to look into the "no solid lines" problem later.

from libmypaint.

rbreu avatar rbreu commented on June 14, 2024

Right. I have no idea what a sensible minimum would be, but I can try playing around with it.

from libmypaint.

briend avatar briend commented on June 14, 2024

@rbreu your changes help but I definitely see the weird noise @martinxyz mentioned. I was able to get pretty solid rakes though. To be clear, are you changing brushsettings.json and bumping up the max dabs? I have to use like 50 dabs per basic radius to get a pretty solid rake. I don't really notice a slowdown with tiny dabs, though. Bigger dabs, yes.

from libmypaint.

rbreu avatar rbreu commented on June 14, 2024

Now I get solid lines, too. I'm not sure what my problem was. (Not the max settings in brushsettings, maybe stroke settings?)

I'm not getting any jitter. Probably dependent on the input device?

from libmypaint.

briend avatar briend commented on June 14, 2024

Much better! I don't notice any "noise" now! You might want to try my patches to increase the curve points. This lets you make much more complicated "rake" brushes, etc. I was always frustrated whenever I'd run out of points. I bumped it up from 8 to 64 (and shrank the size of the point). It requires changes to both libmypaint and mypaint:
https://github.com/briend/libmypaint/tree/curve-points
https://github.com/briend/mypaint/tree/curve-points
in Master, now

from libmypaint.

briend avatar briend commented on June 14, 2024

I made a feature branch here with rbreu's changes (I modified one commit to remove a bunch of whitespace changes) as well as added a state for the "flip"
https://github.com/mypaint/libmypaint/tree/anti_offset

from libmypaint.

briend avatar briend commented on June 14, 2024

I just had an idea. The offset angular side and angular mirrored use the direction that the pointer is going to figure out which direction the dabs should be offset, right? and it's always 90 degrees offset. I noticed that you have to have some initial movement before you put the brush down or else you'll get a few dabs going haywire at the start of the stroke. This is only really annoying for fine detailed strokes.

SO, I was thinking-- assuming we have a tilting pen, we already know the ascension in degrees, why not use that for the direction instead of speed? It would be immune to jitter issues (I think) and simulate a real paint brush more accurately. This could be a new setting, since the current proposed settings actually work with just a mouse and non-tilting stylus, which is nice.

The other idea is similar to the dab angle setting and could able to the existing and new ascension-angle offset settings-- instead of hard coding the angle offset to be 90 degrees, why not allow that to change with another setting. When we get barrel rotation that could be killer combo. What happens when you twist the barrel of a flat brush 90 degrees? The dabs are offset parallel instead of perpendicular to your ascension!

from libmypaint.

briend avatar briend commented on June 14, 2024

I added a Multiplier setting that affects all the offset settings. It is logarithmic so the default value of 0.0 won't affect anything, and won't break any existing brushes. But now you can offset quite a bit more if you'd like. Previously if you had a 1 pixel brush, for instance, you could only offset 10 pixels or so. The limit is ~20X multiplier, so it is somewhat difficult to get into trouble with size, but not impossible. The offset is multiplied by base_radius already, so a large brush can offset ~8,000 pixels now. However I think the custom input can get around this limit, but I don't think we should worry about that. Custom is weird and doesn't seem to have any maximum, and I think that's intentional for flexibility.

With the multiplier mapped to pressure, and a bunch of settings mapped to a custom stair-stepped pattern you can do really useful stuff like this: ;-)
https://gfycat.com/ActualGraciousFossa

from libmypaint.

briend avatar briend commented on June 14, 2024

Ok I added 2 additional offset settings based on the ascension angle instead of direction, as I mentioned earlier. It works very well, no noise, and it adds another dimension to the shape of the brush. But is definitely not a replacement for the original offsets. I also added an offset angle adjustment setting, so you can do really neat stuff like this:

https://gfycat.com/EquatorialAmpleDobermanpinscher

The last thing is to decide if we want to apply the viewrotation calibration to the original offset X, offset Y settings. I would vote yes, because I was trying to add a "dripping effect" a while ago and it was pretty frustrating that my "drips" did not continue to go "down" when I rotated the canvas. Thoughts?

from libmypaint.

briend avatar briend commented on June 14, 2024

@rbreu remember all the weirdness with the dabs and the noise? All that went away when I consolidated the code to use the direction_360 code. Ah, now it takes advantage of the direction_filter. You can get some really cool transitional effects by cranking up the filter to 10.0

from libmypaint.

briend avatar briend commented on June 14, 2024

I did a long random demo. direction_filter is awesome. So now things are more consistent, anything that is direction-related (including offsets and attack_angle) should be using the direction_filter I think.

https://youtu.be/3SYw1zR1gWY

from libmypaint.

briend avatar briend commented on June 14, 2024

Here's a wobbly flatbrush thing to try:
https://gfycat.com/ImperfectFelineAmericanblackvulture
Rename the txt file to myb and put it and the png in your brushes folder.

wobbly_flatbrush.txt
wobbly_flatbrush_prev

from libmypaint.

briend avatar briend commented on June 14, 2024

Well, I think we should leave Offset X and Offset Y as literal X and Y offsets that are NOT affected by canvas rotation. I thought of a pretty cool use for this, well, maybe a bit silly:
screenshot from 2017-06-26 16-33-31

This sort of offset makes sense to "stick" to the canvas no matter how you rotate it. Whereas a brush offset like @AnTi-ArT's dripping brush:
image
Could really benefit from a new set of Offsets settings-- "Offset Up/Down" and "Offset Left/Right". Because things "drip" down, which is always "down" regardless of how you rotate the canvas.

from libmypaint.

briend avatar briend commented on June 14, 2024

This has been merged, but I would like to still create those last two offsets for "up/down" and "left/right". Thanks @AnTi-ArT and @rbreu !

from libmypaint.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.