|
|
||
|
Lightwrap
with CustomTool
This
tutorial owes its existence (and our doggy hero) to an interesting
discussion in the PigsFly forums. I hope it will
benefit a broad range of readers:
novices, beginners, and
newbies alike. I myself am barely into Fusion, but after too many
months
with insert here the name of
that other application that
starts with an 'A' I was so excited with the novelty that
I had an
urge to share my profoundly benign feelings about this piece of
software. But I managed to contain it and decided instead to make this
crappy tutorial about the almighty
CustomTool using lightwraps as an excuse.tutorial for Fusion5 Okay, enough with kidding - let's say that I'm just trying to show how to actually use CustomTools to build more compact and efficient comps. The general principle, of course, is also valid for Shake (channel expressions, I know they are there, somewhere) and the like. Take your time - this stuff is not so trivial after all if you never did 'math compositing', but I'm sure you'll figure out what's happening at each step. If you never happened to use a CustomTool before, you should first read eyeon's excellent page on it to understand its principle of operation and basic syntax - and the page about the Merge tool is another good source of information - okay, close this useless tab and go read the whole vfxpedia thing. Update: I kinda realized that the abovementioned page is actually a bit cryptic for people that keep at safety distance from anything math/scripting (or just beginners), and since these people are the miscredents I want to convert I added quite a bit of general info/explanation here and there. Sorry for the inconvenience (it being the uncomfortable length of this page). Here's
our foreground dog along with his alpha channel
Let's start
with a simple comp: our
first very basic lightwrap is achieved by multiplying our matte to a
blurred and inverted version of itself, and then multiplying
the whole thing by 2 to rescale the range to 0-1. (otherwise
the outer
edge of the resulting matte will have a value of 0.5 because of the
blurring). I'll try to
explain better this last step. Let's take a pixel at the very edge of
our matte; for simplicity suppose its alpha value is exactly 1 (our
matte is quite hard-edged). What we do when we
'simplified-version-of-the-story'-blur this pixel is to take a
certain amount of white (matte) pixels from one side of it and average
them with the same amount of black (non-matte) pixels on the other
side. 20 white pixels averaged with 20 black pixels make a grey pixel,
that means alpha value of 0.5. If we multiply this 0.5 pixel
with the unblurred itself, that was 1.0, we get 0.5. For the very
nature of the operation we're doing this is the maximum value we can
get in our new matte, but it just makes no sense to work in the 0-0.5
range; so by multiplying by 2 we renormalize our matte (that is, we put
it back to a nice 0-1 range). Speaking of colorcorrecion terms, gain
is a simple multiplication (gain of 2.0 = x*2) that only preserves
blacks while gamma is an exponential (gamma of 3.4 = x^1/3.4)
that
leaves the value in the 0 - 1 range, thus preserving both blacks and
whites.![]() The
initial flow and the resulting matte
Note: when I created the
lightwrap I actually had
the custom tools there from the very beginning; I tried to recreate the
flow using many simple nodes for the sake of clarification.Let's get into the juicy stuff: make a CustomTool and connect its Image1 input to the foreground image and the Image2 input to the Blur. We'll start by replicating the functionality of these MatteControl, Merge and ColorGain within one CustomTool (not the blur, though - convolution kernels are unpractical to achieve with non-tiny matrices and painfully slow). So how do CustomTools work? They evaluate frame by frame, pixel by pixel, the per-channel expressions provided in the Channels tab. These expressions can simply be numbers (if you type '0.5' in the Alpha expression, the output will have a solid semitransparent alpha channel); or they can reference channels in the input images by following the scheme 'channel letter+input number ' (the default 'r1' - that stands for 'red channel of input Image1' - in the Red expression takes whatever is in the red channel of the node connected to Image1 and passes it unaltered to the red channel of the output); or they can build new images by combining numbers and channels in the inputs within simple mathematical expressions. In the channels expressions we can now refer to the original foreground matte as a1, while the blurred matte is a2. The resulting Alpha Expression will be pretty straightforward: a1
* (1-a2)
* 2
Let's
go thru this again - refer to the little flow with the notes
above: we took our matte, blurred it (and that, once connected to
Image2, becomes known as a2) then inverted it (1-a2), then merged it with the original matte via an operation In to multiply the two alphas (so (1-a2) * a1) then gained (multiplied) the resulting alpha by 2.
![]() There comes our CustomTool, still shy yet ready to show its prowess ![]() So far, so good ![]() Slowly getting there Leaving the defaults of the ColorSpace, this turns out to be ((0.299r + 0.587g + 0.114b) - LT) * 1/(HT-LT). So now we can pipe our blurred background into Image3 of our CustomTool, set the desired low and high thresholds into Number In 1 and 2 in the controls tab - we refer to them as n1 and n2 in expression lingo - and update our Alpha Expression as follows: a1*(1-a2)*2
* (max ((0.299*r3 + 0.587*g3 + 0.114*b3) - n1),0) / (n2-n1)
We need the max because
inside an expression there's no clamping until the final result, and we
placed it in such a fashion that it clamps the result of our
cheap 'brightness math'. In this case
actually it is not (yet) needed,
since negative values will stay negative throughout the calculation and
eventually get clamped anyway, but I feel safer to put min's and max's
wherever it makes sense, just so we won't quiz for otherwise productive
minutes on why we're getting absurd (though nice) results. Conversely
if we don't
clamp values over 1.0 - and we don't - this whole thing will work
beautifully also with HDR images.![]() CustomTool fears no defeat ![]() This matte looks promising ![]() Dear ol' flow's getting messy max (1 -
max((1- (0.299*r1 + 0.587*g1 + 0.114*b1) - n3),0) / n3), 0)
that gives us a nice clamped matte and that goes as
another factor into our CustomTool's Alpha Expression, provided that
you put the desired value into Number In 3. This
value, however, is not actually a threshold (we'd get a nasty bitmask
out of it) but the value above which the resulting alpha starts
decreasing, with a tighter falloff curve at lower values and a broader
one at high values - and this makes sense anyway. If you
need finer control, just provide the high threshold alongside
and change /n3 to /(n4-n3) just like we did for the
background thresholds. We're almost done. The last touch is to give our lightwrap a nice matte gamma control and a blend control - trivial by now, isn't it? So let's put everything that is lightly'n'lazily lying in our Alpha Expression - which incidentally is everything we have typed so far, since expression chunks are notoriously lazy - in parentheses and add at the very end ^ (1/n5)
* n6
being n5 and n6 the gamma
value and the blend value that we dutifully type in Number In 5 and
Number In 6, of course. We are saying
to take everything and raise it to the power of the inverse of the
gamma value, exactly what 'gammaing' actually does. As for blend, I
still can't figure it out. ![]() Is it really worth the effort? ![]() Easy setup (1 - ((1
- (c1 * a1)) * (1-c2) ) ) * a2
and then put everything
over the background (Image3)+ c3 *
max((a3-a2),0)
We can also feed in another
'premultiplied' control, that when activated will skip the processing
of the foreground by its matte; making it 0 for 'unpremultiplied' and 1
for 'premultiplied' and putting it on n1, we'll end up having(1 - ((1
- (c1*a1)) * (1 -c2))) * max(a2,n1) + c3 * max((a3-a2),0)
![]() I can live with or without you A few more general tips:
Comments, critics, explanation requests, mercilessly pointing out conceptual or even linguistic errors, all of this is tolerated welcome mandatory. If you really have to Feel free to Do it at pigsfly here. |
||