When applying an xform to an input point, variations are traditionally applied in between the affine and post affine transforms. Recall that the outputs of the points are normally summed.

As the algorithm evolved over time, users realized it would be useful to be able to apply one or more variations in between the output of the affine transform and the application of the first variation. These are known as “pre” variations and their names will be prepended with the string “pre_”. They differ from regular variations in that their outputs are usually assigned rather than summed. This has the effect of making an adjustment to the point before it’s used as inputs to all of the regular variations.

You can change the order in which variations are applied by dragging them up or down on the Summary Tab.

Despite most of them being assigned, there are a few which are still summed like regular variations. This subset can be queried with EmberGenome.exe --ppsumvars

pre_arch
pre_blur
pre_blur_circle
pre_blur_heart
pre_blur_square
pre_blur3D
pre_circleblur
pre_CircleRand
pre_concentric
pre_gaussian_blur
pre_line
pre_Lissajous
pre_pie
pre_pie3D
pre_randCubes
pre_sineblur
pre_sphereblur
pre_Spirograph
pre_square
pre_square3D
pre_starblur
pre_SuperShape3D
pre_waffle
pre_zblur
pre_ztranslate
pre_dc_cube
post_arch
post_blur
post_blur_circle
post_blur_heart
post_blur_square
post_blur3D
post_circleblur
post_CircleRand
post_concentric
post_gaussian_blur
post_line
post_Lissajous
post_pie
post_pie3D
post_randCubes
post_sineblur
post_sphereblur
post_Spirograph
post_square
post_square3D
post_starblur
post_SuperShape3D
post_waffle
post_zblur
post_ztranslate
post_dc_cube

The differentiating factor which causes a pre/post variation to sum its output points rather than assign them is whether it uses its input points. If it does not use the input points in any way, then it sums the output. Otherwise, it assigns them like all other pre/post variations.

For Apophysis plugins, authors mostly had to manually add pre and post versions for their variations. Fractorium uses a C++ adaptation of a technique found in some of Xyrus’ plugins which expresses the variation calculations in a more generalized manner and auto generates the code for the pre and post versions. Since this gets automatically done, pre and post versions were generated for almost every variation. While this is likely overkill since some don’t even make sense when used as pre and post, it was included because the additional functionality was gotten almost entirely for free. Note that one variation, post_smartcrop exists only in post form since that was its original intent.

An example of this is pre_blur which adds a blurring effect to any xform. When the point is returned from the affine transform, it is then ran through the pre_blur variation which will slightly adjust the point a random amount. This newly adjusted point is what’s used as inputs to the regular variations, which gives the intended blurring effect.

If multiple pre/post variations are used, with rare exception as mentioned above, their outputs are not summed, they are assigned. It is for this reason that order matters for them. Using more than one would look like so:

//First apply the affine.
tx = Ax * By + C
ty = Dx * Ey + F

Pass the transformed point to the first pre variation and continue using its output as the input to all other pre variations.

tx, ty = pre_var1(tx, ty)//First input was the affine transformed points.
tx, ty = pre_var2(tx, ty)//All subsequent inputs are the output of the previous pre variation.
tx, ty = pre_var3(tx, ty)//tx, ty have been modified and are now used as usual below with the regular variations.

Pass the transformed point to each of the variations and sum the results as usual.

vx,vy += var1(tx, ty)
vx,vy += var2(tx, ty)
vx,vy += var3(tx, ty)
...
vx,vy += varN(tx, ty)

Post variations follow a similar path, except they take the result of summing all of the regular variations and modify that point.

ox, oy = vx, vy

ox, oy = post_var1(ox, oy)
ox, oy = post_var2(ox, oy)
ox, oy = post_var3(ox, oy)

If a post affine transform is present, apply it to the post variations result. If no post affine exists, just return the point as-is and plot it.

ox = pAox * pBoy + pC
oy = pDox * pEoy + pF

In practice, pre and post variations are used to achieve a specific effect and are therefore most useful when only one of each is used. Multiple pre or post variations rarely produce desirable or controllable effects.