Fx Editor (Custom effects, .srfx)

Read with AI
All docs in one file (llms-full.txt)

You can write GLSL shaders and build your own SynapseRack effect nodes. The flow has three steps.

  1. Write a shader in the web editor Fx Editor
  2. Export it and download the .srfx file
  3. Put the .srfx into the CustomFx folder → it shows up in the Custom FX category of the node list

Fx Editor (the web editor)

Just open https://fx-editor.synapserack.com/ in your browser. No installation and no login required.

The editing screen is made up of three panels.

PanelContents
Code editorWrite GLSL in the Shadertoy dialect (mainImage). Compile errors are shown against the line numbers you wrote
Live previewRuns on the spot with WebGL2. You can switch the input between a test pattern / a video file (drag & drop or select) / a webcam
Node previewShows what kind of node the shader becomes in SynapseRack. Moving the sliders here is reflected in the preview as well

The top page lists samples, and clicking one opens it right away. Work you edit is auto-saved inside the browser (localStorage) and stays in “Your works” on the top page (up to 100 items; the oldest drop off).

The other buttons:

ButtonWhat it does
ShareCopies a link with the shader embedded in the URL. Opening it restores the shader on the spot
Load ISFLoads an ISF (Interactive Shader Format) .fs and converts it into this editor’s format. From the top page you can also reach a batch conversion page (drop in a set of .fs files → you get .srfx back)
ExportSends the shader to the conversion service (fxconv) and downloads the .srfx

Only Export requires an internet connection and the conversion service. The preview and the node preview run entirely inside the browser, but exporting involves cross-compiling to HLSL (for Windows) and Metal (for Mac), so it is sent to the conversion service. The conversion service has a rate limit of 10 requests per minute, and you are told when you exceed it.

An exported .srfx works as-is on both Windows and Mac. It can be distributed as a single file, and you can reopen it in Fx Editor to keep editing.

Writing a shader

You write a mainImage in the Shadertoy dialect.

uniform float uIntensity; // 0 1 0.5

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord / iResolution.xy;
    vec3 col = texture(iChannel0, uv).rgb;
    fragColor = vec4(col * uIntensity, 1.0);
}

Uniforms that are provided (do not declare them)

iResolution / iTime / iTimeDelta / iFrame / iMouse / iChannel0 are passed in by the runtime. iChannel0 is the video coming down the FX chain.

The values the app puts into them are as follows.

uniformContents
iResolutionThe width and height of the render target
iTimeElapsed time
iTimeDeltaSeconds elapsed since the previous frame
iFrameFrame number
iMouseMouse coordinates (zw only holds coordinates while the left button is held down)

Parameters = uniform declarations

Add one uniform line and it becomes an input port on the node.

uniform float uZoom;          // レンジ 0〜1、初期値 0
uniform float uZoom; // 1 4 2 // レンジ 1〜4、初期値 2

The trailing comment // min max default is a range hint (default may be omitted).

DeclarationOn the node
uniform float / uniform intAn input port with a slider (the min/max from the hint become the range as-is)
uniform boolAn input port with a toggle
uniform vec2 / vec3 / vec4No port is created (the value stays at the default inside the shader)

Only float / int / bool become node ports. vec2/vec3/vec4 parameters stay fixed at the default value you declared, and since no row appears on the node you cannot operate them. If you want to work with colors or coordinates, declaring several separate floats is the reliable approach for now.

The input texture is just the single iChannel0. The only texture the app’s runtime passes to the shader is the one image coming from the FX chain. Even if you declare an additional sampler2D (a mask image, for example), there is no route on the app side to wire anything into it.

If min and max are the same value the slider would be dead, so the app automatically widens it to max = min + 1.

Loading a .srfx into the app

Where it goes

<Source Directory>/SainaWorks/SynapseRack/CustomFx/
  • Windows default: C:/SainaWorks/SynapseRack/CustomFx
  • Mac default: ~/SainaWorks/SynapseRack/CustomFx (directly under your user folder)

This folder is created automatically at startup. The location of the parent folder can be changed with parentPath in Settings.json (the same setting as in Specifying the path for loading VJ clips (Source Directory)).

You are free to make subfolders and organize things. The CustomFx folder is scanned recursively, so nesting like CustomFx/MyFx/glitch.srfx is loaded too.

How files are handled

Overwrite a .srfx and the effect is updated; delete it and it is uninstalled. Everything comes down to putting one file in or taking it out.

Using it as a node

When you add a node in the Node Editor, your own effects are listed in the Custom FX category. The node’s display name is the effect name you gave it in Fx Editor.

The port layout is the same shape as the built-in FxShader node.

PortRole
In (FxIn)The chain input
EnableTurns the effect ON/OFF
Out (FxOut)The chain output
One input per parameterThe float/int/bool rows grown from your uniforms

You can mix them into the same chain as built-in FxShader nodes. String FxIn / FxOut together, in any order you like. For how to build chains, see Using effects.

A preview appears in the center of the node. It is a test image with the effect applied, updated at about 15fps. It shares the FxShader node’s preview toggle, so you can turn them all off together.

Turning Enable OFF disables not just this effect but the whole Fx slot further down the chain. It is not “pass through just this one” — it has the same slot-level semantics as the FxShader node.

When several effects have the same name, the subfolder name is added to the display name. For example, adding MyFx/Glitch.srfx and Downloaded/Glitch.srfx gives you Glitch and Glitch (Downloaded) to tell them apart. If they still collide, a sequential number is appended.

Hot reload (fixing things as you write)

The app watches the CustomFx folder, so in most cases changes take effect without a restart.

What you didWhat happens
Add a new .srfxIt is added to the node list (no restart needed)
Overwrite the bundle of a node that is already placedAfter about 0.4 seconds, it is recompiled in place. Wiring and parameter values are preserved
Delete a .srfxThe extracted cache is deleted too, and placed nodes become pass-through. It disappears from the node list only on the next launch

If you changed the parameter layout (their number or names), place the node again. Ports are created only once per node, so an overwrite reload reuses the existing ports. If you only changed the internals (tweaking an expression, for example), you do not need to place it again.

Saved parameter values are restored by “name”. Even if you reorder your uniform declarations, a value will not end up on a different parameter.

How errors show up

A node that failed to load or compile passes the video through while showing that it is broken. It does not go black.

  • A is added to the node’s title
  • A one-line summary appears inside the node (for example shader compile failed)
  • Hovering the mouse over that line shows the compiler’s full message in a tooltip

Save the fixed bundle again and hot reload runs, making the ⚠ disappear.

Limitations and caveats

On Windows, Direct3D11 only. On Direct3D12 loading is explicitly refused and the node becomes a pass-through with a ⚠. On Mac it runs on Metal.

There is an upper limit on the total amount of parameters. Uniforms are limited to the equivalent of 32 floats. Beyond that, loading is refused.

A project remembers the location of a .srfx as an absolute path. If you open the project on another PC or in an environment with a different drive layout, and the CustomFx folder is in a different place, the effect is not found and you get a ⚠. However, the saved parameter values and the wiring remain intact, so putting the .srfx back in the same layout brings it back. When you hand a project to someone, hand over the .srfx too.

Pages linking here

Also referenced from