-or both could be scaled. That means four chains.
-
-Now remember that we need to create all your chains both in high-
-and low-quality versions. In particular, this determines the “hq”
-parameter to finalize(), but in our case, we would want to replace
-ResampleEffect by *ResizeEffect* (a simpler scaling algorithm provided
-directly by the GPU) for the low-quality versions. This makes for
-eight chains.
-
-Now also consider that we would want to deal with *interlaced*
-inputs. (You can check if you get an interlaced input on the Nth
-input by calling “signals:get_deinterlaced(n)” from get_chain.)
-This further quadruples the number of chains you'd need to write,
-and this isn't even including that you'd want the static chains.
-It is obvious that this should not be done by hand. The default
-included theme contains a handy Lua shortcut called
-**make_cartesian_product** where you can declare all the dimensions
-you would want to specialize your chain over, and have a callback
-function called for each possible combination. Movit will make sure
-each and every of those generated chains runs optimally on your GPU.
+or both could be scaled. That means four scenes. However, you don't need to
+care about this; behind the scenes (no pun intended), Nageru will make all
+four versions for you and choose the right one as you call enable() or
+disable() on each effect.
+
+Beyond simple on/off switches, an effect can have many *alternatives*,
+by giving in an array of effects. For instance, it is usually pointless to use
+the high-quality resampling provided by ResampleEffect for the on-screen
+outputs; we can use *ResizeEffect* (a simpler scaling algorithm provided
+directly by the GPU) that instead. The scaling is set up like this::
+
+ local input0 = scene:add_input()
+ input0:display(0)
+ local input0_scaled = scene:add_effect({ResampleEffect.new(), ResizeEffect.new()}) -- Implicitly uses input0.
+ scene_or_input.resample_effect:set_int("width", 1280) -- Just like before.
+ scene_or_input.resample_effect:set_int("height", 720)
+
+ -- Pick one in get_scene() like this:
+ input0_scaled:choose(ResizeEffect)
+
+ -- Or by numerical index:
+ input0_scaled:choose(1) -- Chooses ResizeEffect
+
+Note that add_effect returns its input for convenience.
+
+Actually, add_optional_effect() is just a wrapper around add_effect() with
+IdentityEffect as the other alternative, and disable() is a convenience version of
+choose(IdentityEffect).
+
+Actually, more versions are created than you'd immediately expect.
+In particular, the output format for the live output and all previews are
+different (Y'CbCr versus RGBA), which is also handled transparently for you.
+Also, the inputs could be interlaced, or they could be images, or videos (see
+:ref:`images` and :doc:`video`), creating many more options. Again, you
+generally don't need to care about this; Movit will make sure each and every of
+those generated scenes runs optimally on your GPU. However, if the
+combinatorial explosion increases startup time beyond what you are comfortable
+with, see :ref:`locking`.