New input: SurfaceMap (canvas texture, etc)

https://github.com/briend/libmypaint/tree/surfacemap

Here’s a really cool input that lets you create textures, patterns, or really crazy brushes based on a pattern you define in a grid form. In some sense you can think of this as a bump map of the actual texture-- the ridges are sharp and pick up the paint, and the valleys are shallow and create transparent areas. However, this analogy only works for opacity and lightness; other settings like radius, jitter and color are just cool to play around with. How does it work? It’s pretty simple; it takes your X (or Y) coordinate and performs a modulo operation to get a number that “wraps around”. For X,Y coordinates 300,310 with a scale factor of 2^8, you’d have values 44 and 54 (300 % 256 and 310 % 256). Whatever scale factor you use it will be scaled to a range of 0-256 so that we can have a consistent range for our brush settings control.

This gives you a basic “canvas” texture that is pretty predictable (opacity):

With the scale factor you can make the pattern bigger or smaller to suite your brush and painting dimensions, etc.

Finally here are some real examples. You can get some very crazy and interesting brushes. It is pretty fun to add several surface maps controlling radius, opacity, etc, and see what kind of patterns emerge when scribbling a large area.

2 Likes

I made a demo video of a fractal-like pattern. Brush settings are at the end of the video:

2 Likes

This looks really awesome to say at the least. Question though is it possible to have the brush react to the background layers texture? Like applying a bump map or normal map to the background layer, and then have a couple of parameters for how it behaves on those maps? It would seem much more user friendly that way than havering a brush which has a specific texture applied to itself. Granted having these parameters will give brushes a more unique look though so it still an awesome feature to add to MyPaint. Keep up the great work!

Thanks for the feedback! Pulling color data from the canvas and translating that into a bump map and into the SurfaceMap brushsettings is wayyy beyond my knowledge. I’ve only added a couple lines of code here. BUT, I wonder if there is a way to combine two brushes. Maybe we can create a “background brush” and save it as something like “heavy cotton canvas” or whatever. So you pick the background (which is really just a brush) and then any other brush, and whatever settings (that are defined) in the second brush will override the first brush, a merge basically. That could be really useful for other reasons beyond having textures and whatnot. You could create combos and have a way to modify every brush in your collection on-the-fly in a consistent way.

Very cool!

Haven’t tried it yet, so maybe it’s there already, but maybe you could add some velocity-depend stuff in there too, to simulate the fact that the bristles or whatever you are painting with, will be dragged along the sides of the surface bumps? Well, really just some differential might be enough, so that you can dynamics depending on whether you are moving up- or down-hill? I. e., some parameter related to the surface map value now minus the previous value.

Anyway, really good work!

Thanks! The SurfaceMap is just like any other brush input, so it can modify any of the settings. So I guess the hard part is figuring out what it means in mypaint-settings-terms to drag the bristles up the side of the slope? Maybe it means the dab-ratio changes from 1:1 to 1:9? That might be interesting. If you have @AnTi offset patch you could try the X and Y offsets w/ SurfaceMap that might also work to displace the dabs up or down as they go up/down over the SurfaceMap, I haven’t tried that but it might be cool.

Here’s another demo, this time with “round” pattern and automatic zoom scaling of both the brush radius and the SurfaceMap pattern. In the previous demo the scale was modified by the surfacemap itself, and I manually ticked the brush size down as I zoomed in. If you want to try it out w/ the zoom thing you really need to use my everything-but-the-kitchen-sink branch here:

https://github.com/briend/libmypaint/tree/all-newinputs
and
https://github.com/briend/mypaint/tree/all-newinputs

This includes a bunch of stuff that I’m trying to separate out and make small patches for. It also includes @AnTi patches for offset and direction

1 Like

I’ve added a couple more settings-- SurfaceMap Scale X, and Y. What I’d like to do is be able to change the scale on-the-fly in either of these directions independently. My thinking is that if you have a pattern defined it probably looks like a flat 2D texture. However, if you could tilt your pen and modify the scale of the SurfaceMap in just one direction, it could make the pattern appear to “turn” as well. So you might be able to “sculpt” 3D looking shapes by manipulating the scale in either or both directions. Trouble is I think it would have to be tied to both Tilt and Ascension in a direct way. That is, tilting 45 degrees to the East would be different than tilting 45 degrees to the North. I can imagine without any tilt at all the texture scale would be unmodified.

1 Like

I’ve been playing around with it. It’s pretty fun!

The drawback is that the pattern only comes out when the dabs are a lot smaller than the pattern. I think I understand why this is, coding-wise (pattern only affects the property of a dab as a whole), but it’s pretty confusing that the same settings works like a charm on the pencil and charcoal brushes (with their tiny dabs) but seems to do nothing for things like water brushes or broad markers who have long elliptical dabs. Took me a while to figure out why. :wink:

Thanks! Yeah, I forgot to mention that pesky limitation :-P. Actually I think I convinced myself it was a “feature”. My thinking was that if you were making a rubbing of something, like a tree leaf, you would expect that the smaller tool would extract more pattern from the leaf than the larger tool. See, you wouldn’t expect a water brush to pull the pattern, right? Feature! :wink: