|
In the service of building a trivial color suppression macro, this
tutorial illustrates two really important concepts in Shake: thinking
in parallel, which will influence the overall design of the macro, and
variable dependencies in macros, which will come into play when we get
into the implementation details.
Many artists make the mistake of thinking about what they're doing in
Shake on the level of individual pixels and end up writing expressions
on ColorX/LayerX/WarpX nodes in order to build up effects that vary
based on input pixel values. Unfortunately, by their very nature as
general-purpose tools these nodes are nowhere near as efficient as
their special purpose cousins like Add or Mult. Thinking of operating
in parallel, as if on the image as a whole, every pixel at once, rather
than on individual pixels, can lead you to build much more efficient
processing trees. Unfortunately, many of us get in the habit of
thinking serially and trying to specify pixel-by-pixel what we want
Shake to do. For example, to suppress the level of green in a pixel to
the level of blue in it, we might use a ColorX node with the gExpr
parameter set to
(g > b) ? b : g
which means, "if green is greater than blue, use blue, otherwise use
green". This would indeed give us the result we're after: green values
unchanged where they don't exceed blue, and clipped at blue otherwise.
We could also implement it more simply as just
min(g, b)
The output is again the blue values where green exceeds blue and green values where green is less than blue.
Unfortunately both of these require use of ColorX. The whole thing
would work a bit faster if we could find a way to do it with built-in
nodes optimized for their particular tasks rather than ColorX. In this
case, we could reorder the channels so that the two inputs to the Min
node were the green and blue channels separately and the output was
copied back into the green channel of the original image, giving us
exactly the same result as the expression on ColorX did but gaining the
efficiency of the optimized Min node. What about all this extra work to
reorder the channels around the Min? On the surface this seems
counterproductive, using four nodes rather than one, but Shake's built-in nodes are highly optimized and we also get the benefit of caching between nodes. In the long run, and
particularly for complex operations and adjusting in the UI, the result is much more
efficient than executing an arbitrary function for each pixel. For a one-off, this may not be worth the effort, but for
something you might use over and over or turn into a macro, the
efficiencies can add up to big improvements in overall render times..
Continue Tutorial: 1 2 3 4 
|