Skip to content

Plugin Development

Zoltán Dócs edited this page Apr 17, 2024 · 4 revisions

In IFSRenderer, each transform is a plugin in the form of .ifstf files. These are small GLSL snippets with extra markup. Contrary to DLL plugins, they are compiled at runtime, so it's easy to get started with just a simple text editor.

Managing plugins

The portable version stores them in the Library\Transforms directory next to the executable. The installer version stores them in the user's AppData under the same name (C:\Users\username\AppData\Roaming\IFSRenderer\Library\Transforms\). The list of transforms in the editor window is loaded by reading this directory, which means you can just drag & drop and edit files here. Then, above the list of transforms is a reload button which reloads every plugin without needing to restart IFSRenderer. A message box shows the error if one of the plugins failed to load.

Plugin interface

These two lines are required to identify a plugin:

@Name: My Awesome Plugin
@Version: experimental

As you can see, the value of version can be any string. It's used just to tell whether the currently loaded fractal was made with this version of the plugin. The user is notified in case params are loaded using a different plugin version. @Description is an optional field which is shown to the user in the transform's info panel. @Tags is again optional, and has multiple purposes: first, the user can search tags to quickly find transforms, e.g. for "glitch" style fractals. Second, it helps IFSRenderer - both the node editor and the generator - handle plugins the intended way. For example transforms with the "shape" tag are always generated with Add=1 and Opacity=0.
The input to transform is p which is a vec3. The output is a vec3 too, which you must return at the end.
Here's a simple example Cylinder.ifstf:

@Name: Cylinder
@Version: 0.1
//optional
@Description: Cylinder transform aligned on the Y axis.
@Reference: https://github.com/bezo97/IFSTransforms/
@Tags: test, my-tag
//define custom variables
@Radius: 1.0

//'p' is a vec3 input
float r = 0.5 + 0.5 * dot(p.xz, p.xz) / @Radius;
vec3 cyl = vec3(p.x / r, p.y, p.z / r);
//remember to return a vec3 output
return cyl;

In this example @Radius is a custom variable that the user can modify in the editor.

Notes

  • There's a built-in way to easily generate random numbers, use random(next) call to get a uniform random float in range 0-1.
  • You can do return discarded_point; to reset the iteration state.
  • iter_depth is an input of type int. It is the current iteration depth. Feel free to experiment with it.

Using shared code in transforms

In case you want to share common functions, constants etc. among transforms, you can do so by placing files containing glsl snippets in the Library/Includes/ directory. These will be inserted in the compute kernel to be used in transforms.
In the transforms where you want to use shared code, add the following line in the header: (any extension is accepted)

@Use: my-common-lib.txt

Make sure to package these files along with released transforms otherwise users won't be able to load them.

Transforms repository

The default transforms included in IFSRenderer are hosted in a separate repository bezo97/IFSTransforms. Feel free to open a discussion to include new default plugins.
There's also bezo97/ifsr-attractors transform pack for inspiration.