Kalles Fraktaler 2+ Manual

Kalles Fraktaler 2 +

As the orginal upstream author Karl Runmo says:

Want to create DEEP Mandelbrot fractals 100 times faster than the commercial programs, for FREE? One hour or one minute? Three months or one day? Try Kalles Fraktaler!

It works by using perturbation techniques and series approximation, to allow faster lower precision number types to be used for pixel iterations, based on a high precision reference.

I (Claude Heiland-Allen) forked the code and swapped out the custom arbitrary precision floating point code for highly optimized libraries, making it even faster. Cross-compiled to Windows from Linux MINGW64. Now with many other enhancements.

Original upstream version:

This version:


Quick Start


Known Bugs

Differences From Upstream 2.11.1

Incompatible Changes

Other Changes

Change Log


User Interface


Newton-Raphson Zooming




Getting The Code

I distribute EXEs bundled together with the corresponding source code.

The latest source code is available from my git repository:

git clone https://code.mathr.co.uk/kalles-fraktaler-2.git
cd kalles-fraktaler-2
git checkout master       # for Karl's original upstream
git checkout claude       # for MINGW build system and bug fixes
git checkout kf-2.14      # old stable (bugfixes only)
git checkout kf-2.15      # for current development
git tag -l                # list available release tags

You also need et to generate the formula code for Newton-Raphson zooming:

git clone https://code.mathr.co.uk/et.git

This is outside the scope of this document at the moment, easiest is to download the release bundle and copy the formula/generated folder from the included src zip. Get in touch for help if you want to regenerate these sources yourself.

Building On Linux

Compiling KF for your own CPU is recommended for optimal performance. The performance boost can be significant, as the release EXEs are compiled for generic i686 and x86_64 but newer CPUs have additional instructions available. This is less important now that OpenCL is available, as this optimizes for your hardware at runtime.

Note: there is an upstream bug in the GCC compiler. On Debian the compiler is patched in recent versions. Patching it yourself is not hard, but it does take a long time and need about 30GB of disk space. Without a patched compiler, KF may crash in SIMD code due to 32-byte aligned moves with a 16-byte aligned stack. See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=939559. Contact me if you need help to patch your compiler.

Build instructions for cross-compiling from GNU/Linux require about 10GB of disk space and good internet download speed (or patience). About 750MB of downloads including the chroot debootstrap step. If you have recent Debian you can skip the chroot step and install natively.

  1. Setup Debian Buster chroot:

     sudo mkdir ./vm
     sudo debootstrap buster ./vm/
     sudo mount proc ./vm/proc -t proc
     sudo mount sysfs ./vm/sys -t sysfs
     sudo cp /etc/hosts ./vm/etc/hosts
     sudo chroot ./vm /bin/bash
  2. Install dependencies (inside the chroot if you made one):

     dpkg --add-architecture i386
     echo >> /etc/apt/apt.conf.d/30buster 'APT::Default-Release "buster";'
     echo >> /etc/apt/sources.list 'deb http://deb.debian.org/debian bullseye main'
     apt update
     apt install \
       build-essential \
       cabal-install \
       cmake \
       ghc \
       git \
       libghc-parsec3-dev \
       libtool \
       lzip \
       m4 \
       p7zip \
       pkg-config \
       wget \
       wine32 \
       wine64 \
       wine-binfmt \
       xsltproc \
     apt install -t bullseye \
     apt install \
       pandoc \
       texlive-fonts-recommended \
       texlive-latex-recommended   # for PDF manual
     mount binfmt_misc /proc/sys/fs/binfmt_misc -t binfmt_misc
     update-binfmts --import /usr/share/binfmts/wine

    For Ubuntu replace “wine32 wine64 wine-binfmt” with “wine” (but see note about build failures with some versions).

  3. Compiling is possible with GCC (well-tested) and LLVM (experimental, supports ARM).

    For GCC, configure the system MinGW compilers to use win32 threading model (instead of posix). If you don’t do this then you’ll get mysterious weird behaviour (like zooming out resetting zoom to infinity or 0).

    Choose the manual win32 alternative for all of these, you can ignore failures for gfortran and gnat if they are not installed:

     update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-win32
     update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-win32
     update-alternatives --set x86_64-w64-mingw32-gfortran /usr/bin/x86_64-w64-mingw32-gfortran-win32
     update-alternatives --set x86_64-w64-mingw32-gnat /usr/bin/x86_64-w64-mingw32-gnat-win32
     update-alternatives --set i686-w64-mingw32-g++ /usr/bin/i686-w64-mingw32-g++-win32
     update-alternatives --set i686-w64-mingw32-gcc /usr/bin/i686-w64-mingw32-gcc-win32
     update-alternatives --set i686-w64-mingw32-gfortran /usr/bin/i686-w64-mingw32-gfortran-win32
     update-alternatives --set i686-w64-mingw32-gnat /usr/bin/i686-w64-mingw32-gnat-win32

    If you have existing builds build with posix threading model, you should delete them or move them out of the way, as mixing win32 with posix leads to a world of pain and misery (as does mixing LLVM with GCC).

  4. Prepare non-root build user:

     adduser build
     # enter and confirm password
     su - build
     mkdir -p ~/win/src

    If compiling with LLVM, install the MinGW toolchain (needs ~15GB space):

     mkdir -p ~/opt/src
     cd ~/opt/src/
     git clone https://github.com/mstorsjo/llvm-mingw.git
     cd llvm-mingw/
     ./build-all.sh ~/opt
     export PATH=${HOME}/opt/bin:$PATH
  5. Download Kalles Fraktaler 2 + sources:

     cd ~/win/src
     git clone https://code.mathr.co.uk/kalles-fraktaler-2.git
     cd kalles-fraktaler-2
     git checkout kf-2.15
  6. Download and build and install 3rd party library sources (inspect the script if you want to be sure it isn’t doing anything dodgy, or to copy/paste parts if necessary), the script can build both 64bit and 32bit variants if necessary:

     cd ~/win/src/kalles-fraktaler-2
     bash ./prepare.sh dl
     bash ./prepare.sh x86_64
     bash ./prepare.sh i686
     bash ./prepare.sh aarch64
     bash ./prepare.sh armv7
  7. Download the latest version of Kalles Fraktaler 2 + and copy the et-generated formulas from it:

     cd ~/win/src/kalles-fraktaler-2
     wget -c "https://mathr.co.uk/kf/kf-$(wget -q -O- https://mathr.co.uk/kf/VERSION.txt).7z"
     7zr x kf-*.7z
     cd kf-*/
     unzip kf-*src.zip
     cd kf-*-src/
     cp -avit ../../formula/generated formula/generated/*.c
  8. To build Kalles Fraktaler 2 + optimized for your own Intel/AMD 64bit CPU:

     cd ~/win/src/kalles-fraktaler-2
     make clean
     make SYSTEM=x86_64+native -j $(nproc)
  9. To build Kalles Fraktaler 2 + for generic 32bit Intel CPU:

     cd ~/win/src/kalles-fraktaler-2
     make clean
     make SYSTEM=i686 -j $(nproc)
  10. To build Kalles Fraktaler 2 + for generic 64bit CPU:

     cd ~/win/src/kalles-fraktaler-2
     make clean
     make SYSTEM=x86_64 -j $(nproc)
  11. To build Kalles Fraktaler 2 + for generic 32bit ARM CPU (might not work due to a bug in GMP):

    cd ~/win/src/kalles-fraktaler-2
    make clean
    make SYSTEM=armv7 -j $(nproc)
  12. To build Kalles Fraktaler 2 + for generic 64bit ARM CPU:

    cd ~/win/src/kalles-fraktaler-2
    make clean
    make SYSTEM=aarch64 -j $(nproc)
  13. To build Kalles Fraktaler 2 + release (all architectures + documentation + source zip + everything 7z + signing):

    cd ~/win/src/kalles-fraktaler-2
    ./release.sh $(git describe)

Note: build fails on Ubuntu 16.04.3 LTS (xenial):

$ make
x86_64-w64-mingw32-g++ -mfpmath=sse -xc++ -Wno-write-strings -pipe -MMD -g -O3 -ffast-math -I/home/claude/win64/include -DKF_THREADED_REFERENCE_BARRIER -o fraktal_sft/CDecNumber.o -c fraktal_sft/CDecNumber.cpp
In file included from fraktal_sft/CDecNumber.cpp:1:0:
fraktal_sft/CDecNumber.h:5:76: error: 'decNumber' was not declared in this scope
 typedef boost::multiprecision::number<boost::multiprecision::gmp_float<0>> decNumber;
fraktal_sft/CDecNumber.h:5:76: error: template argument 1 is invalid
fraktal_sft/CDecNumber.h:5:62: error: template argument 1 is invalid
 typedef boost::multiprecision::number<boost::multiprecision::gmp_float<0>> decNumber;
fraktal_sft/CDecNumber.h:5:62: error: template argument 2 is invalid
fraktal_sft/CDecNumber.h:5:32: warning: 'typedef' was ignored in this declaration
 typedef boost::multiprecision::number<boost::multiprecision::gmp_float<0>> decNumber;
$ x86_64-w64-mingw32-g++ --version
x86_64-w64-mingw32-g++ (GCC) 5.3.1 20160211
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO

The working Debian Buster with compiler from Bullseye (needed for the SIMD alignment fix mentioned above) has:

$ x86_64-w64-mingw32-g++ --version
x86_64-w64-mingw32-g++ (GCC) 10-posix 20200525
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO

Building on Windows 64-bit (may be adaptable to 32-bit)

Note these instructions are out of date.

Build instructions for compiling on Windows (thanks to knighty and Patrick Owen!):

  1. Remove any old version of MSYS2.

    These instructions assume you are using a fresh version of MSYS2. Depending on how confident you are, you may be fine skipping this step.

  2. Download the latest version of MSYS2 from https://www.msys2.org/ (msys2-x86_64-20190524.exe).

  3. Run it to install MSYS2. When the installation finishes, the MSYS2 shell should open.

    Note: Many files you interact with in future steps are in the installation directory of MSYS2. It is recommended that you install MSYS2 on a drive with plenty of space, as there will be about 10 gigabytes of files in there at the end of the installation process.

  4. In the MSYS2 shell, invoke pacman:

     pacman -Syuu

    You will need to keep running this command until is says “there is nothing to do”. While it’s running, it may ask you to close the terminal. Follow these instructions. When you open the terminal again (see step 5), keep running the command.

  5. Close the MSYS2 shell:

  6. Reopen the MSYS2 shell (from startup menu, under the name MSYS2 MSYS).

  7. Install mingw/gcc 64 bit (this will take a fair bit of time):

     pacman -S mingw-w64-x86_64-toolchain

    When it asks you to enter a selection, just hit enter (all).

  8. Install required tools (this will likely take less time):

     pacman -S --needed git patch make diffutils mingw-w64-x86_64-cmake lzip p7zip unzip
  9. Close the MSYS2 shell then open “MSYS2 MinGW 64-bit” shell (instead of MSYS2 MSYS, in order to have all the environment variables properly set)

  10. Install tar. The version of tar that comes installed with MSYS2 has trouble extracting xz files.

     pacman -S tar
  11. Restart MSYS2 again (Close and reopen “MSYS2 MinGW 64-bit”).

  12. Install ghc (Haskell)

    # See https://gitlab.haskell.org/ghc/ghc/wikis/building/preparation/windows
    curl -L https://downloads.haskell.org/~ghc/8.6.5/ghc-8.6.5-x86_64-unknown-mingw32.tar.xz | tar -xJ -C /mingw64 --strip-components=1
  13. Change directory to the kalles fraktaler sources (where Makefile resides).

    If this directory is outside of the msys64 directory, include the full Windows path, replacing backslashes with forward slashes and drive letters like C:\ to paths like /c/.

  14. Download and build and install 3rd party library sources (inspect the script if you want to be sure it isn’t doing anything dodgy, or to copy/paste parts if necessary), the script will need to be modified to build the 32bit version:

    bash ./prepare-msys.sh dl
    bash ./prepare-msys.sh 64

    The first script is relatively fast depending on your internet speed, as it downloads dependencies. Depending on the speed of your machines, the second script takes about an hour to run.

    The script has several places where it pauses for a while with no output. You will know that it has finished successfully when it shows a bunch of lines starting with “– Installing:” and then exits, giving you back control of the command line.

  15. Download the latest version of Kalles Fraktaler 2 + and copy the et-generated formulas from it:

    cd "/path/to/Kalles Fraktaler 2 +"
    wget -c "https://mathr.co.uk/kf/kf-$(wget -q -O- https://mathr.co.uk/kf/VERSION.txt).7z"
    7zr x kf-*.7z
    cd kf-*/
    unzip kf-*src.zip
    cd kf-*-src/
    cp -avit ../../formula/generated formula/generated/*.c

    Feel free to delete kf-*/ and kf-*.7z inside your git repository afterwards.

  16. To build Kalles Fraktaler 2 + optimized for your own CPU:

    cd "/path/to/Kalles Fraktaler 2 +"
    make clean
    WINDRES=windres make SYSTEM=x86_64+native -j $(nproc)

    Note that mingw32-make does not properly detect that files are already up-to-date, making building slow each time. Use make instead.

  17. To build Kalles Fraktaler 2 + release:

    Follow the instructions for Linux, possibly making adaptions to allow them to work with MSYS2

  18. Execute it this way from (MSYS2 MinGW 64-bit) command line:


    because it is linked dynamically to some libraries. In order to execute it from the explorer one needs to copy libwinpthread-1.dll from msys64/mingw64/bin next to the generated executable.

Kalles Fraktaler 2 +

Copyright (C) 2013-2017 Karl Runmo

Copyright (C) 2017-2021 Claude Heiland-Allen

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/.

NOTE: If you redistribute the binaries or provide access to the binaries as a service, you must also be prepared to distribute the source corresponding to those binaries. To make this easier for you, the more recent zips include the source too (though you’ll also need to get the third party library sources).

Library sources can be obtained via:


Thanks to:

Claude also thanks Karl for releasing the source code and assigning a Free Software license.

User Manual






At the very top right:

Status bar



Formula dialog

Hybrid Formula dialog

Bailout dialog

Colors dialog

The Colors dialog is accessed via the Fraktal menu, or via the keyboard shortcut Ctrl+C in the main window.

OpenGL dialog

The OpenGL dialog is accessed via the OpenGL button in the bottom left of the Colors dialog, or via the keyboard shortcut Ctrl+G in the main window.

OpenGL Shader Language API

OpenGL Shader Language basic syntax is similar to C or C++ (braces and semicolons). KF provides a number of preset uniform variables and a small library of functions which you can use to access the raw iteration data in the neighbourhood of a pixel (random access is not possible due to the tiled rendering used for larger images). KF’s default colouring algorithm (and modularized subparts) are also available for use in custom code.

The GLSL fragment should implement a function with this name and type signature:

vec3 colour(void);

The default colouring can be emulated by using KF_Colour:

vec3 colour() { return KF_Colour(); }

There should be no #version line in the GLSL fragment, instead __VERSION__ should be used to adapt to the environment.

float49 numbers

To avoid precision loss when representing iteration counts, a float49 type is available which has 49 bits, compared to only 24 bits for regular float. GLSL does not have operator overloading (only function overloading) so you can manipulate them with these functions:

add neg sub mul inv div sqr ldexp
is_zero is_one is_positive is_negative
gt lt ge le eq ne abs max
fmod divrem drem nint aint floor ceil
exp log log10 pow sqrt nroot
sin cos tan sincos asin acos atan
sinh cosh tanh sincosh asinh acosh atanh

Some constants are also available:

f49_nan f49_inf f49_0 f49_1 f49_e f49_log2 f49_log10
f49_2pi f49_pi f49_3pi4 f49_pi2 f49_pi4 f49_pi16
f49_eps f49_min_normalized f49_max

You can convert a float49 to float by f.x[0], and to double by double(f.x[0]) + double(f.x[1]).

Accessing pixel data

The following functions get data for the current pixel, or for a nearby one if an ivec2 offset is passed. The maximum absolute useable pixel offset is in uniform ivec2 KFP_TilePadding. See the documentation of the exported EXR channels for semantics.


Returns true when the current (or offset) pixel is glitched.


Returns true when the current (or offset) pixel is interior.


Returns the uint most significant 32bits of the iteration count of the current (or offset) pixel.


Returns the uint least significant 32bits of the iteration count of the current (or offset) pixel.


Returns the float smooth part of the iteration count of the current (or offset) pixel.


Returns a float49 of the current (or offset) pixel’s smooth iteration count, calculated by (N1 << 32) + N0 + (1.0 - NF) in 49 bits of precision.


Returns a float of the current (or offset) pixel’s phase of final iterate (normalized to [0..1)).


Returns a float of the current (or offset) pixel’s horizontal analytic distance estimate (normalized to 1.0 being a neighbouring pixel’s boundary).

Requires derivatives to be enabled in the Formula dialog.


Returns a float of the current (or offset) pixel’s vertical analytic distance estimate (normalized to 1.0 being a neighbouring pixel’s boundary).

Requires derivatives to be enabled in the Formula dialog.


Returns a vec2 combining the current (or offset) pixel’s analytic DEX and DEY.

Requires derivatives to be enabled in the Formula dialog.


The base-2 logarithm of the current (or offset) pixel’s zoom level. Unzoomed is 0.0, deeper zooms are larger.

See palettes/claude/text-overlay.glsl for an example using this to display text.


Returns true when the provided offset relative to the current pixel (not absolute coordinates!) lies inside the image bounds. The bounds can be found in uniform ivec2 ImageSize.


Get output coordinates, relative to the uniform variable ImageSize. Origin is bottom left per OpenGL conventions.


Return the vec2 jitter delta of the current (or offset) pixel. Uses the uniform variables uint KFP_JitterSeed, int KFP_JitterShape and float KFP_JitterScale.

Not available in zoomasm. Numerical (non-analytic) distance estimation also cannot use jitter. Analytic DE with derivatives is recommended.


Fills three mat3 with the relative iteration counts and pixel positions (offset plus jitter) of a 3x3 stencil centered on the current pixel. Used for numerical distance estimation. Returns the center pixel’s float49 N.

Distance estimation

A 3x3 stencil of relative iteration counts can be used for numerical distance estimation.

KF_DE(int method)

Returns numerical distance via a differencing method, one of the following #defined constants:


Note: Differences_LeastSquares2x2 and Differences_LeastSquares3x3 are not implemented in GLSL, and Differences_Analytic uses the DEX and DEY channels which require derivatives to be enabled in the Formula dialog.


Return DE via KF’s original implementation.


Return DE via 3x3 forward differences.


Return DE via 3x3 central differences.


Return DE via 2x2 diagonals, aka Robert’s Cross.


Return DE via 3x3 Laplacian.


Return DE via derivatives.

Accessing colouring parameters

The following uniform variables are set from the Colors dialog:

ivec2 ImageSize

The size of the final image.

sampler1D KFP_Palette

The key colours of the palette. The function KF_Palette interpolates the palette emulating KF’s regular implementation, input is in [0..1).

vec3 KFP_InteriorColor

The interior colour.

bool KFP_ShowGlitches

Whether the menu option Advanced -> Show Glitches is selected.

uvec2 KFP_Iterations

The iteration count. [0] contains the least significant word, [1] the most significant word.

uvec2 KFP_IterationsMin

The minimum iteration count achieved in the image.

uvec2 KFP_IterationsMax

The maximum escaped iteration count achieved in the image.

float KFP_IterDiv

Divide iterations.

float KFP_ColorOffset

Color offset.

bool KFP_Smooth

Smooth colouring.

bool KFP_Flat

Flat colouring

bool KFP_InverseTransition

Invert colour transition. Can be applied to float49 iteration counts with the function KF_InverseTransition().

int KFP_Differences

Numerical differencing method. See above.

int KFP_ColorMethod

Color method, one of the following #defined constants:


The float49 iteration counts can be transformed by the ColorMethod (including distance estimation, IterDiv, ColorOffset, InverseTransition) can be applied with the function KF_IterTransform()

float KFP_PhaseColorStrength

Phase color strength.


bool KFP_Slopes

Whether slopes are enabled.

float KFP_SlopePower

Slope power.

float KFP_SlopeRatio

Slope ratio.

vec2 KFP_SlopeDir

The cosine and sine of the slope angle, suitable for dot products.

vec4 KF_Slopes(bool Analytic, vec2 SlopeDir, float Power, float Ratio)

This API function implements slope colouring emulating KF’s default colouring. The return value s can be combined with the background colour bg with mix(bg, s.rgb, s.a);

Infinite waves

There are up to KFP_MultiWavesCountMax waves (a constant, currently 32):

bool KFP_MultiWavesEnabled

Whether waves are enabled.

bool KFP_MultiWavesBlend

Whether waves should be blended.

int KFP_MultiWavesCount

How many waves are added.

ivec3 KFP_MultiWaves[KFP_MultiWavesCountMax]

The wave data. The ivec3 contains period .x and type .z, the .y coordinate is currently not used. Only the first KFP_MultiWavesCount slots are filled.

vec3 KF_InfiniteWaves(bool Smooth, float49 N)

This API function implements infinite waves emulating KF’s default colouring.

Image texture

bool KFP_TextureEnabled

Whether image texture is enabled.

sampler2D KFP_Texture

The texture.

float KFP_TextureMerge

Image texture merge.

float KFP_TexturePower

Image texture distortion power.

float KFP_TextureRatio

Image texture distortion ratio.

vec2 KF_TextureWarp(float TexturePower, float TextureRatio, vec2 SlopeDir)

This API function implements image texture distortion emulating KF’s default colouring. Example usage:

if (KFP_TextureEnabled)
  vec2 tc = getCoord() + KF_TextureWarp(KFP_TexturePower, KFP_TextureRatio, KFP_SlopeDir);
  tc /= vec2(ImageSize.xy);
  s = mix(s, texture(KFP_Texture, tc).rgb, KFP_TextureMerge);

Information dialog



i            -- imaginary unit (square root of -1)
p            -- integer power between 2 and 5 (10 for Mandelbrot)
c = a + i b  -- pixel coordinates (parameter plane)
z = x + i y  -- iteration variable
w = u + i v  -- temporary variable for two-stage formulas
f = d + i e  -- constant 'a' for TheRedshiftRider formulas
l m ...      -- juxtaposition is multiplication
^            -- raise an expression to a positive integer power
|.|          -- surrounding a real-valued expression: absolute value


A machine-readable version of this formula list is found in the ‘et’ repository: https://code.mathr.co.uk/et/blob/kf:/kf/formulas.et This is used by ‘et’ when generating formula code (for Newton-Raphson zooming, etc).

Command Line Usage

kf.exe [options]
    -o, --load-map      [FILE.kfb]  load map file
    -c, --load-palette  [FILE.kfp]  load palette file
    -l, --load-location [FILE.kfr]  load location file
    -s, --load-settings [FILE.kfs]  load settings file
    -x, --save-exr      [FILE.exr]  save EXR
    -t, --save-tif      [FILE.tif]  save TIFF
    -p, --save-png      [FILE.png]  save PNG
    -j, --save-jpg      [FILE.jpg]  save JPEG
    -m, --save-map      [FILE.kfb]  save KFB
        --save-kfr      [FILE.kfr]  save KFR
    -z, --zoom-out      [NFRAMES]   zoom sequence
    --log (debug|status|info|warn|error)
                                    logging verbosity
    -v, -V, --version               show version
    -h, -H, -?, --help              show this help

Locations and settings can also be image files with embedded comments.

If any of the save options are give, KF switches to a non-interactive mode - it will render the image and save to all specified types before quitting. No GUI.

A typical workflow would be to start KF without arguments, set up the window size (eg 640x360), image size (eg 3840x2160), glitch low tolerance flag, etc, then save the settings to a .kfs file, before quitting.

Then launch KF from the command line telling it to load the settings file you just saved, plus the location file you want to render, and where to save the output images to. Then wait patiently. You can write a script that renders multiple locations in succession, either in batch .BAT on Windows, or in Shell .sh on *nix with WINE.

Note that you might have to double up backslashes within quoted paths (if they contain spaces). Maybe forward slashes work instead, but you do need quotes (either single '' or double "", in a matching pair around the whole argument) if there are spaces. Your shell might also do funky stuff with slashes and quotes, so you might need to double up or quadruple up the backslashes and quotes. Easiest to avoid spaces and keep your files in the current working directory… Example:

kf.exe -s settings.kfs -l location.kfr -p out.png -j out.jpg -x out.exr

Use --log info to disable the status updates, use --log warn to output only important messages. The default is --log status.

With -z you can specify how many frames to render, or -1 to zoom all the way out. In zoom out mode the output save filenames should contain a printf flag for an integer, for example image-%08d.png will have 8 decimal digits padded with leading 0. This is filled by the frame number, which always starts from 0. Zooming is by the zoom size in the settings file.

New in 2.14.6 is standalone KFB map colouring support with the -o/--load-map flag:

kf.exe -o map.kfb -c palette.kfp -p out.png

The -o/--load-map flag can also load raw iteration data from EXR.

New in 2.14.10 is KFR writing, if no image files need to be rendered it is very fast to output a zoom sequence (note: no auto-iterations support in this mode).

Tiled Rendering

Tiled rendering is useful for large images, including images larger than the 2GB pixel data limit of Windows bitmaps. The currently supported way of rendering tiled images is via EXR files, though there are some Octave/Matlab scripts still available that can work with more common image files.

Example: target final size 64000x36000, tile factor 10x10. Configure image size to 6400x3600, adjust other settings, save input.kfs and input.kfr. Then run (syntax for Bash shell):

kf-tile.exe input.kfs input.kfr 10
for tile in input-*.kfs
  kf.exe -s ${tile} -l ${tile%.kfs}.kfr --save-exr ${tile%.kfs}.exr
exrtactile.exe input 10 0 output.exr  # for side-by-side tiles
exrtactile.exe input 10 1 output.exr  # for stratified tiles

You can append one argument at the end of the kf-tile.exe command:

The EXR tile assembler is available at https://mathr.co.uk/exrtact including Windows program binary.

Third-party Software



exrtact is a suite of small command-line programs for manipulating EXR files. Of particular note is exrtactile for tile assembly (see above).



zoomasm is a zoom video assembler for turning exponential map EXR keyframe sequences into movies. It has a timeline system in which you can set zoom depth at specific times, for example to synchronize with a soundtrack.



git clone https://code.mathr.co.uk/kf-extras.git

kf-extras is a suite of small command-line programs for manipulating KFB files. Programs include colouring algorithms (curvature, histogram, pseudo-de, rainbow, stretch) and other tools (de-histogram, expmap, resize, statistics, to-exr, to-mmit) as well as a bash script to generate a zoom video (which needs the mightymandel zoom assembler below). The programs use a small library to abstract the KFB and PPM reading and writing, which can be used as a basis for your own programs.

After Effects zoom tools


saka on fractalforums.org is working on a plugin for Adobe After Effects:

I’m working on a plug-in for Adobe After Effects. It renders from the .kfb file data generated by Kalles Fraktaler. I will release the plug-in as open-source, but of course Adobe products are not free.

It’s still very much a work in progress, but I thought I’d share in case anyone is interested in trying it out at this early stage. It might have some bugs.

Why After Effects? It provides a pretty solid animation, layering and rendering engine. All the settings can be animated, and it is easy to build layered compositions using KF data. Plus having 4k and 8k export in various codecs is appealing.

Requirements: After Effects 2019, Windows only.

See fractalforums.org for downloads and tutorials.

Key Frames Movie Maker


The original Movie Maker by Karl Runmo. Has controls for changing speed, rotation, colour cycling, and more, at specific frames. Also has an option for zoom depth text overlay. Works from KFB files and generates multiple video file segments.

Yann Le Bihan’s Movie Maker 3D


Works from KFB files and generates video segments with a 3D effect:

This Manual is formed as a tutorial describing the steps to make a movie with 3D effect, which includes all settings.

Dinkydau’s Mandel Machine Convertor

Mandel Machine is a fast Mandelbrot renderer for Windows written in Java and assembly.

Dinkydau on fractalforums.org has written:

something to convert the MMI file format to KFB

so that Mandel Machine glitches can be corrected in KF or KF renders can be coloured in Mandel Machine. But Dinkydau has not released it. Maybe if you ask nicely you will be granted access. More information at:


SeryZone’s Map Visualizer and Fractal Video Maker

Dinkydau on fractalforums.org has written:

My favorite zoom video maker (it only creates PNG sequences) is SeryZone’s kfb map visualiser. It’s hard to use because of the very not-intuitive interface though.


With this tool you can create PNG images from KFB maps and use them as keyframes with the other tool fractal video maker. Use fractal video maker to interpolate extra png files, for example 60 between each keyframe for a 60 fps zoom video at a speed of 1 zoom per second. (where by “zoom” I mean an increase in magnification by a factor 2, which is the recommended zoom size in kalles fraktaler)


Later in that thread are download links for the tools.

mightymandel zoom interpolator

mightymandel is a Mandelbrot set renderer using OpenGL.


It has a zoom assembler in its extra subfolder.


usage: zoom iwidth iheight iframes olength [ofps [oshutter]] \
  < stream.ppm > stream.y4m

It is a bit picky about the format of the input PPM stream, and input frames must be 2x zoomed at each frame from zoomed out to zoomed in. Arguments:

iwidth: input frame width

iheight: input frame height

iframes: input frame count

olength: output video length in seconds

ofps: output frame rate (25fps default)

oshutter: motion blur (0 no blur, 1 full blur, 0.5 default)

You might need to downscale the input PPM stream to something your GPU can manage, noting that the internal code needs a texture 2x bigger than the input/output frames. Up to 4096x4096 input should be ok on most modern cards. The output dimensions are the same as the input. For best quality downscale after zoom interpolation, not before, if possible.

et zoom interpolator

et is an escape time fractal project implemented in Haskell.


It has a forked version of the mightymandel zoom interpolator optimized for distance estimation rendering. Usage is the same as the mightymandel zoom interpolator except that the input is raw headerless floating point data (single channel containing distance estimate, normalized to 1 for the neighbouring pixel).

The difference to the mightymandel zoom interpolator is that it interpolates the DE data before colouring instead of after, which gives a much smoother image (no strobing filaments). Output size is hardcoded to 1920x1080, you can edit this near the top of the main() function in zoom.c before compiling. Input frame size should be as large as possible for best quality.

The program has two more arguments compared to the mightymandel zoom interpolator: whether to output a header (set to 1 unless you know what you are doing) and an “inverse video” flag that makes it white on black instead of black on white. The output Y4M stream is mono, you might have to tell ffmpeg to encode -pix_fmt yuv420p for some codecs.

usage: zoom iwidth iheight iframes olength \
  [ofps [oshutter [header [inverse]]]] < stream.raw > stream.y4m

zoom-tools zoom-interpolator


zoom-tools is a suite of small command-line programs for turning EXR zoom sequences into zoom videos. It has filters for input keyframes and output video frames, allowing video files to be encoded without needing so much temporary disk space.

zoom-tools has been obsoleted by zoomasm.

“book” zoom interpolator

The mightymandel zoom interpolator is better in every way (it is based on the same code, just enhanced). And the book repository is 60MB because it has images. But if you want to study it for historical reference:

wget -O Makefile https://code.mathr.co.uk/book/blob_plain/HEAD:/code/Makefile
wget -O zoom.c https://code.mathr.co.uk/book/blob_plain/HEAD:/code/zoom.c
make zoom

Or using git (note: the repository is large):

git clone https://code.mathr.co.uk/book.git
cd book/code
make zoom


./zoom iwidth iheight iframes olength < stream.ppm > stream.y4m

File Formats

EXR Channels and Metadata

Discussion about a common format for escape time fractal data is taking place here:


Here are the channels and metadata that KF currently supports: