Follow by Email

Monday, April 2, 2012

An Anatomy of Painter's Brushes, Part 2

Blogging during Spring break is tough without a Mac, especially when eats your post! I'm using blogsy on an iPad to lay out my post, and, I must confess I am using Paper by fifty-three to illustrate this post. When I need to crop, straighten, or adjust, I then use iPhoto. I try out all the mobile paint apps and I am quickly becoming a veteran of many trials and tribulations of the mobile environment.

Normally I use traditional ultra-fine Sharpie on 30# paper so it doesn't leak through. In Preview, I scan the line art using a Canon scanner that sits on my home network. Also in Preview, I tonally adjust and scale to appropriate dimensions for the blog. Quite often, somewhere in between, I use Painter to adjust, clean up stray lines, and apply coloring on a gel layer.

Sometimes I do my illustrations entirely in Painter because, along with the Wacom tablet, it is really an excellent drawing environment, rivaling the natural medium. But often I do my scribbling on a clipboard because, as you know, I am always sketching. When I get an idea, I like, to sketch it out.

This post concerns a unique aspect of Painter's brushes: the constant work done improving and re-improving upon the bristle brush model. It all started in 1991, when I was working on the very first version of Painter. One day I got the idea that it might not be all that difficult to create multi-bristle brush strokes.

My first try, which users got a look at in September 1991, when Painter was initially released, was the Van Gogh brush. This brush (1) recorded the brush stroke and then (2) played it back several times with some locational jitter applied to each stroke, and some color jitter (in HSV) applied to each stroke about the center color. This really was a magical amplifier to a brush stroke and it served to show me how powerful multi-bristle brushes could be. It could produce some great results. And it's not to be confused with the Auto Van Gogh effect, which extracts directions from the image and then re-renders it using thin dabs of multi-colored paint. That is one effect that can benefit from all the advances in direction vector field extraction and vector field visualization.

My second try came in Painter 2.0 with the rake brush. I worked on this in late 1992, while Tom Hedges and Bob Lansdon were working on the first version of watercolors. You can see the notes I drew for the initial idea. The bristles are placed on the circumference of a circle (cylinder) and the brush direction becomes the primary angle that determines which bristles are in contact with the canvas. That's the first sheet. In the second sheet, we see a bit about how we compute the exact points of contact for the brush stroke. In the third sheet I introduces a splay parameter that widens the potential number of bristles that come in contact. On the first sheet on the bottom row, I detail how opacity can fall off at the edge of the stroke and also how turning the brush (meaning changing brush stroke direction) can sequence through the bristles that contact the canvas. The last two sheets show the effect of curving the brush stroke and how the bristles exit and enter.

The rake brush was an interesting look, yet it really was only good at creating parallel arrangements of contact between the brush and the canvas. And, it only had one color well.

My next attempt was in the Painter 3 timeframe in 1994, and it was the bristle brush. This brush simply took a speckle, which is a random set of mutually-avoiding points in the plane, and used it to model the tight-packing of bristles within a brush itself. So I took the contact area of the brush, which I modeled as a circle, and used it to clip the speckle. The color of the brush was then rendered in the current well color, and there was, once again, only one color well for the brush. This was really just a shortcut for capturing a brush that contained multiple bristles in it. I think the reason I went for these simplistic solutions was that the compute power of the machines Painter was targeted for was quite limited. It's hard for me to think in those terms today, unless I start thinking more about the limits to the compute power of the iPhone and iPad environments.

Also during the Painter 3 timeframe, I made the Van Gogh brush work in real time while drawing the brush stroke. This probably didn't improve the look of the results, however.

There were plenty of brush advances in the Painter 4 and 5 timeframes, but I didn't really return to bristle brushes until Painter 6.

In 1998, I began working on brushes again using a separate environment from Painter, an environment called the San Marco development environment. Eventually this entire development framework was simply thrown away. But in the meanwhile, I used it to mock up the multi-bristle brush, the spatter airbrush, and the brush where an image, masked by its alpha channel, was mapped into the space of the brush, like a raster version of Alex Hsu's Expression brush. He called his technology Skeletal Strokes, but this shows what engineers do poorly: name their technology. It's lucky I was part marketer too.

The new code was implemented using C++, unlike Painter, which was implemented entirely in C and assembler (!). When we got to the Power PC, we raised the assembler used for the inner loop of the brush code back into C.

So there was a period in 1999 when Painter 6 was being written when I was gluing these technologies together. And the result was excellent. The camel hair brush was the result. This brush was great because it modeled every bristle separately and rendered it using a single pixel line. The line was colored according to its own color well, so each bristle effectively had its own color well. This meant the brush could be loaded with color, potentially a different color per bristle. Also, each bristle could keep a slightly different color in it, using color jitter.

But more importantly, each bristle had its own path across the canvas. To remedy the problem that there weren't really enough samples from the mouse or stylus, I built a way to smooth the path of the brush stroke. And introduce new samples, to avoid the visible vector stepping in the stroke. To do this, I created a FIFO to implement cubic interpolation. For every 4 points, I could create however many points I wanted in between the middle two points. I think I created three points in between them. This made the strokes much smoother but also introduced some squirrelly behavior. So I turned off interpolation when the speed of the brush went below a certain velocity or when the stroke made a sharp turn.

Another problem that needed to be solved in multi-bristle brushes was the stickiness of the paint and it's effect on controlling the brush bristles, and keeping them in check. To do this, I used a form of exponential damping (which also can describe part of the way the color well works). If you keep an accumulator for each scalar quantity, in this case, one for x and one for y, and call it a, and you receive a new x or y value (called s) periodically, you can update the accumulator in the following way: a' = a*(1-d) + s*d. Here d represents the fraction towards which we interpolate to the new value of s. The lower the value of d, the more relaxation on the sample values.

The problem of projecting the bristle positions individually onto the canvas was handled by computing the Frenet frame of the stylus and projecting a speckle of bristles in 3D onto the canvas, forming the updated bristle positions. The frame of the stylus was computed using the tilt and bearing values produced in real time by the Wacom stylus. It also had a pressure, and high pressure could be used to keep the tip closer to the canvas, while low pressure would signify greater distance from the canvas.

I used the same principles for the spatter airbrush, to great effect.

Along with the damping, the positions of the bristles could be known and relaxed into a very natural brush stroke.

Painter has a feature slider. This is used to control the average minimum distance between the bristles in both the bristle brush and the camel hair brush.

I know that Corel has also advanced the state of the art with their new bristle brush, but I can't play with it at the moment. On the next post in this series, I will discuss it, and also show some examples of the various bristle brush strokes.






No comments:

Post a Comment