This is a paint-with-goo brush. It would be easiest
as a magic tool, but might be even better as some
sort of check-box tool option for regular painting.
The idea is to paint with something that looks like
toothpaste, puffy fabric paint, caulk, or similar.
You need highlights and shadows. Painting in grey
might look somewhat like metal, or just grey goo.
Painting could work like this:
As the brush moves, it paints to a hidden greyscale
canvas. Updates to the main canvas are computed
from the hidden canvas. The hidden canvas is disposed
of when the mouse button is released, or possibly when
switching tools. (the choice makes some drawings
easier at the expense of others; it determines if mouse
release causes a new layer of goo on top of the old one)
The hidden layer should be linear, not sRGB.
Goo rendering is like an emboss operation, but tinted.
(see the tinter code for making a pallete; do NOT run
the tinter code for every pixel)
Apply a gaussian blur to the hidden layer. You could
save this data, but you won't be needing it later so it
is better to not save it. Compute the normal vector of
the height field of the blurred data. Compute the angle
between this vector and a vector that points to the
light source. (presumed to be toward the top of the
drawing, probably not to either side or maybe you
should localize this for RTL/LTR languages, probably
with the light source at infinity, probably with the light
source elevated at 45 degrees)
Use that angle as an index into a color look-up table.
The table is the one I hinted at above, generated from
running the tinter code for all brightness values. The
table should already be in sRGB form, avoiding the
need to do a conversion for every pixel.
Mask the output against the hidden canvas. You will
want to do this earlier of course, allowing you to avoid
doing calculations for data that will not be used.
|