I've been noting a number of threads on the list about enhancing the brush tools - leading to the gradient brush, image hose, and so on. Of course, as soon as a new brush is invented, someone wants to add some new functionality to it. (And with every new feature, the paintbrush code gets more complicated, and bits of code get copied between the paintbrush and the pen and the pencil...) I would like to propose a brush model and implementation which should satisfy even the most feature-hungry user. The core idea is to make explicit the processing steps between the mouse motion and the brush application, and replace the current, fixed sequence with an editable sequence of user-programmable plugin processes.
Disclaimer - I looked over someone's shoulder for about thirty seconds a few months ago when they were using a (the?) Photoshop image hose plug-in (or whatever it is). This is obviously similar, but I don't know how close it is.
There are three main components in the new brushing engine:
inp and out. Filters which require input
parameters take the first from modulation channel inp[0], the
next from inp[1], and so on. Generated values are written to
out[0] and so on.
Obviously, filters can be added to or removed from the filter list. So now, any existing or new brush effect can be used with a spray can just by adding a spray filter to the stack, which randomly jiggles the position in the current call. But let's get interesting. Let's write the spray filter so that it takes two modulation inputs, and adds a scaled amount of each input to the x and y values. Using two random modulation generators will give us a standard spray can effect. Instead, let's feed it with the two output channels of a sin/cos cyclic modulation generator which we've placed in the stack. Now we have an "orbiting brush" effect, where the brush actually circles around the cursor as we paint.
If we put the randomised spray filter before the position interpolator, then our brush strokes are all slightly randomly positioned - not so exciting when drawing by hand, but it might be an interesting effect when using rulers.
Or we can create a filter that calls the next filter twice; once with the original values, and once with the position offset by a fixed amount (and, for fun, the colour dimmed slightly). This gives us a double pen effect. (Sadly, the attributes of the two pens can't be set differently by downstream filters. Or can they? Instead of adjusting a specific attribute ourselves, let's just call the next filter N times, and also output a mod channel which steps from 0.0 to 1.0 in steps of 1.0/(N-1). Now we're getting somewhere...)
Some more filters: a canvas filter, which adds texture to any brush stroke by adjusting the alpha channel of the brush according to a background pattern. A filter which varies the fg colour slightly on each call. An alternate interpolation filter to replace the standard brush path interpolator, and produce smoothed curves from the mouse motion. A bristle filter which randomly removes bits of the alpha channel as the brush progresses.
What mod generators are there? We could start with noise, cyclers (sin and cos, triangle, ramp); pen pressure and tilt are obvious, but we can also derive the current angle of the brush path and place that in a modulation channel. There are filters that just process existing mod channels, for example multiplying two channels, or low pass filtering. An envelope generator resets with every new brush stroke, increases to a maximum and then decreases - feed it into a brush fader to get the current brush fadeout effect, but with far more exotic possibilities. A filter which takes a mod channel and maps it through an arbitrary curve would be fun.
So what about the poor user? Well, to start with they don't need to see any of this. The standard brush tools each just set up the appropriate filters to do what they've always done. There might be some interesting differences; for example, the spray tool could become just a toggle to add a spray filter and some random modulators to the current stack, whatever it might be.
Of course, if they're interested, users can open up the brush engine editor. If they do, they are presented with the current stack of filters, and a menu for selecting new ones. Alongside the filter stack run the modulation channels, looking a lot like an old VCS3 patch panel (or maybe more like an ARP 2500. No, go and look it up!); the horizontals are the filter inputs and outputs, the verticals are the modulation channels, and clicking on a crosspoint connects the input or output to that channel. They can add and remove filters from the stack, drive the filters from different modulation channels, and generally play to their hearts' content. Next, of course, they will want to save and restore their new setups ... now, our collection of tools starts to expand like our selection of image filters. Maybe that resizable toolbox came just in time.
Comments to David Hodson or the gimp developers' mailing list.