YOUR ACCOUNT

A script is a program in a computer language that is executed within Filter Forge – more specifically, within Map Script and Curve Script components. Essentially, scripting allows you to program your own components with custom inputs and internal logic. Scripts in Filter Forge are written in Lua.

This article assumes that you are already familiar with the following:

Example #1: Running Your First Script

This section is a quick tutorial that demonstrates running a simple script. We wish we could use the industry-standard "Hello World" example, but Filter Forge doesn't have string output functions, so we'll demonstrate a simple radial gradient generator:

Radial Gradient GeneratorRadial Gradient Generator

Here's the code in a text form so you can copy/paste it into a Map Script component:

function prepare()
end;


function get_sample(x, y)
	d = math.sqrt (x*x +  y*y)
	return d, d, d, 1
end;

Follow these steps to run this code in Filter Forge:

Let's take a closer look at the example script.
As you may have guessed, the image generation happens within the get_sample() function, which accepts two coordinates x and y as arguments and returns the output color calculated based on these coordinates. The color is returned as a list of four numbers, which represent RGBA channels. There's another function, prepare(), which normally handles precalculation and querying non-mapped  inputs, but in this particular script it is left empty – it does nothing.

To generate the gradient, the script calculates the distance between the sample point (given by the two coordinates) and the point with coordinates of 0, 0 (the top-left corner of the image); and simply returns the distance as a color.

Note that the sample script has no loops over pixels or any other form of iteration – it just specifies the image function to be called by the Filter Forge renderer or components. Filter Forge components don't produce images by painting their pixels directly. Instead, Filter Forge 'asks' a component "what color your image has at coordinates x and y?", and the component 'answers' with four RGBA values. In other words, the resulting image is implicitly defined by the component, as opposed to being explicitly painted by it. For more information on Filter Forge's approach to image generation, see Filter Forge's Sample-Based Architecture.

Example #2: Adding Inputs to a Script

Like other Filter Forge components, script components can have map inputs, curve inputs and numeric inputs. Unlike the built-in components that have a hard-coded set of inputs, script components let you define custom inputs via the Input Editor dialog. In this example, we will run a simple script that queries the state of a single checkbox input named Tick:

Adding Inputs to a ScriptAdding Inputs to a Script

Here's the script. Note that it has a line that refers to an input named 'Tick':

function prepare()
chk = get_checkbox_input(TICK)
end;


function get_sample(x, y)
	if chk then
		return  1, 1, 1, 1
	else
		return  0, 0, 0, 1
	end;
end;

Follow these steps to get this script to run:

Now you should see an error message in the Message Log. The error is shown because the script refers to an input named TICK but can't find an input with a Script Identifier of TICK in the Input Editor. Let's open the Input Editor to create this input, and try to run the script again:

Let's take a look at the script.
The prepare() function, which was empty in the first example, now includes a call to the get_checkbox_input() function and stores its returned value in a variable named chk. The only argument of the function is the Script Identifier of the checkbox input we want to query.

This function call is the most important part of this example – it queries the checkbox input with the given Script Identifier, and returns its state as either true or false (in this case it means 'checked' or 'unchecked', respectively.)

In order to execute correctly, the Script Identifier passed to the function must match the Script Identifier specified for the input in the Input Editor. If there's no input in the Input Editor with such Script Identifier, or the input with the matching Script Identifier is not a checkbox input, the script will terminate with an error.

Different kinds of inputs are queried using different functions – checkboxes are accessed via get_checkbox_input(), sliders via get_slider_input() etc. Mappable inputs, such as Color Map Input, Grayscale Map Input and Curve Input, must be sampled by calling their corresponding functions from within get_sample(), while numeric inputs, such as Checkbox Input or Slider Input, must be queried from prepare(), as shown in the example script above. For a full list of input types and their corresponding query functions, see Referencing Inputs from Scripts.

To simplify the task of referencing inputs, the Input Editor displays code snippets showing you how to query or sample each type of input. These snippets will work when pasted into the script, so you don't have to remember the details or refer to this article every time you add an input.

Example #3: Map Inputs and Sample Coordinates

This example is probably the most important – we'll be working with Map Inputs, which are the cornerstone of Filter Forge's power and flexibility. The script in this example implements a simple distortion component that has two map inputs – one for the source image, and another for the distortion map whose RGB channels will determine the direction and amount of distortion:

Working with Map Inputs

Here's the script. Note two calls to a get_sample_map() function:

function prepare()
end;


function get_sample(x, y)
	rd, gd, bd, ad =  get_sample_map(x, y, DISTORTER)
	samplex = x + (rd +  bd/2) * ad
	sampley = y + (gd +  bd/2) * ad
	
	
	r, g, b, a =  get_sample_map(samplex, sampley, SOURCE)
	return r, g, b, a
end;

Follow these steps to run this script:

Let's look at the script.
The whole idea of this example is to demonstrate how map components (including map scripts) do their work by calling get_sample() functions of components connected to their inputs during the execution of their own get_sample() function.

The example script above issues two get_sample_map() calls. The first call obtains the RGBA values of the distortion map at the original sample coordinates specified by the x and y arguments of script's own get_sample() function, and the second call obtains the RGBA values of the source map at distorted coordinates, which are calculated before the call and stored in samplex and sampley variables. The RGBA values obtained at the coordinates after distortion are returned as the final color.

Note that the second get_sample_map() call uses different sample coordinates than the original sample coordinates supplied to script's own get_sample() via its x and y arguments. Filter Forge components, including scripts, are free to sample their map inputs any number of times at any sample coordinates, and they can use the RGBA values returned by these calls in any manner, including the calculation of sample coordinates for subsequent samplingcalls, as in the example script above. For more information on sampling and Filter Forge's coordinate system, see Filter Forge's Sample-Based Architecture.

Note that input sampling functions such as get_sample_map() must be called from script's get_sample() function. If you call them from prepare(), the script will terminate with an error. For more information, see Referencing Inputs from Scripts.