7.3 Combining effects
The effect framework offers a few expressive ways to combine effects to create new types of effects. The primitive effects can be kept simple only if the means to combine them exists. This section is about how to combine simple effects to create more sophisticated ones. It is worth familiarizing yourself with effect-stack and layers because you’ll be using them a lot.
All these functions which transform one or a collection of effects into an effect are collectively referred to as effect combinators and fall into the category of higher order functions.
7.3.1 effect-stack
(effect-stack (effect "Rotate" (A) (param "degrees" 15.0)) (effect "Scale" (A) (param "x" 0.7) (param "y" 0.7)))
(effect-stack (effect "Rotate" (A) (param "degrees" 15.0)) rest-of-the-stuff)
The rest-of-the-stuff is rotated by 15 degrees.
(effect-stack (effect "Rotate" (A) (param "degrees" 15.0)) (effect-stack (effect "Scale" (A) (param "x" 0.7) (param "y" 0.7))))
i.e. the rest-of-the-stuff can itself be seen as an effect stack.
7.3.2 transition-stack
Similar to effect-stack except that the last entry in the stack must be a transition - i.e. a two-input effect and the other must be one-input effects.
7.3.3 layers
The layers primitive combinator is the way to put together a scene in parts. For example, you might want to present a single picture with four different colorations, Andy Warhol style. layers will help you compose such compound scenes.
(layers input-pattern effect1 effect2 .... effectN)
The input-pattern has the same form and purpose as the input pattern specification for effects. The most important point to note here is that effect1, effect2 etc. must be zero-input effects. We will use the term layer to refer to zero-input effects hereafter.
7.3.3.1 An example
Say we want to place four space-shifted copies of a picture or video with decreasing transparencies to create a motion-blurred appearance.
(layers (A) ; input x-shift opacity (shifted-translucent A 0.0 0.6) (shifted-translucent A 0.2 0.4) (shifted-translucent A 0.4 0.2) (shifted-translucent A 0.6 0.1))
(define (shifted-translucent A x-shift opacity) (effect-stack (effect "Alpha" (Shifted) (param "Alpha" opacity)) (effect "Translate" (Scaled) (param "x" x-shift)) (effect "Scale" () (input 0 A) ; ’A’ comes from function parameter (param "x" 0.4) (param "y" 0.4))))
Here is what the composition looks like -
7.3.3.2 Explicit inputs
(input index the-input)
Knowing that the shifted-translucent function should compute a zero-input effect tells us that the last entry of the effect-stack that we use must be a zero-input effect as well.
The Scale effect is normally a one-input effect. We therefore turn it into a layer for the above example by explicitly specifying its input as what was given to the make-shifted-translucent function as its A parameter. We do that using the input form which has the following general structure -
The inputs to an effect are numbered from 0. Therefore 0 for index means the first input, 1 means the second input, etc.
The ability to explicitly specify inputs is essential to many kinds of layer compositions such as what we did above.
7.3.4 remap-time
(remap-time fstart fstop fx) → effect |
fstart : fraction |
fstop : fraction |
fx : effect |
(define muvee-segment-effect (remap-time 1/3 2/3 (effect "Sepia" (A))))
- gives you a segment effect that operates for only the middle 1/3 of a segment.
fstart is in the range [0.0, fstop) and
fstop is in the range (fstart, 1.0].
remap-time doesn’t combine two or more effects, but is useful when combining two or more effects using, say, layers.