Designer Plugins
Plugins for Disguise Designer software.
Plugins for Disguise Designer software.
This guide provides an overview of how to use expressions in Disguise to dynamically control layer properties. It covers both the expression syntax and how to apply expressions using the Python API.
For a complete reference on expression syntax and features in Designer, see the Expressions Overview in the Disguise User Guide.
Expressions in Disguise are powerful tools for creating dynamic and automated visuals. They are evaluated on every frame and can control both numeric and text-based properties of layers.
selfThe self keyword is the default expression for any property. It represents the property’s current animated or keyframed value. You can use it as a base for more complex expressions. For example, self * 2 will double the original value of the property.
Disguise provides several built-in variables that you can use in your expressions:
| Variable | Description |
|---|---|
self | The original keyframed value of the property. |
self.min | The minimum allowed value for the property. |
self.max | The maximum allowed value for the property. |
time | The current track time in seconds since the track started. |
Expressions can use a variety of built-in functions to perform calculations and manipulate values. Here are some of the most common ones:
| Function | Description | Example |
|---|---|---|
math.sin(x) | Sine of x (radians) | 0.5 + 0.5 * math.sin(time * math.pi) |
math.cos(x) | Cosine of x (radians) | math.cos(time * 2 * math.pi) |
min(a, b) | Returns the smaller value | min(1, osc:fader1) |
max(a, b) | Returns the larger value | max(0, self - 0.1) |
lerp(a,b,t) | Linear interpolation between a and b by t (0 to 1) | lerp(0, 100, osc:fader1) |
clamp(x,a,b) | Clamps x between a and b | clamp(osc:fader1, 0.1, 0.9) |
ifYou can use if statements to create conditional logic within your expressions. The syntax is if(condition, value_if_true, value_if_false).
| Example | Description |
|---|---|
if(osc:button1 > 0, 1, 0) | If the value of osc:button1 is greater than 0, return 1. Otherwise, return 0. This is useful for creating a simple on/off switch. |
if(time > 10, self, 0) | If the track time is greater than 10 seconds, use the layer’s keyframed value. Otherwise, set the value to 0. |
if(module:video.frameNumberDisplay < 50, 0, 1) | If the current frame number of the “video” layer is less than 50, return 0. Otherwise, return 1. This can be used to trigger an event at a specific frame. |
You can access and manipulate almost any object in your Disguise project using expressions. These objects are referred to as “Resources”.
There are two primary ways to identify a resource:
type:name syntax. For example, projector:"projector 1" refers to a projector named “projector 1”. If the name contains spaces or special characters, it’s best to enclose it in quotes. If not, you can replace spaces and special characters with an underscore (_), like projector:projector_1.getByUID() function, like this: getByUID(0x123875234).Once you have a reference to a resource, you can access its properties (or “fields”) using the . operator. For example, to get the x position of a projector, you could use projector:projector_1.offset.x.
Here are some common fields:
| Field | Description |
|---|---|
description | The name of the resource as a string. |
offset | The position of the object relative to its parent (e.g., offset.x). |
rotation | The rotation of the object relative to its parent (e.g., rotation.y). |
scale | The scale of the object relative to its parent (e.g., scale.z). |
Note: If you try to access a field that is empty (or None), the expression will fail. You can use an if statement to check if a resource exists before trying to access its fields.
Expressions can directly access data from external protocols, allowing you to control your visuals with live inputs.
| Protocol | Syntax | Example |
|---|---|---|
| OSC | osc:/address | osc:/d3/helloworld |
| DMX | dmx:universe.address or dmx16:universe.address | dmx:1.1 (8-bit) or dmx16:3.20 (16-bit) |
| MIDI | midi:note or midi:cc | midi:60 (note C4) or midi:cc1 (mod wheel) |
You can create powerful links between layers by referencing properties from other layers within an expression.
Note: When referencing a layer or resource with spaces in its name, you must replace the spaces with underscores (_). For example, a layer named “video effects” should be referenced as video_effects.
Prefixes help to adapt values to a property’s expected range.
| Prefix | Description | Example |
|---|---|---|
limit:: | Clamps the result to the property’s min/max range. | limit::osc:fader1 |
scale:: | Scales a 0-1 input value to a property’s full min/max range. | scale::osc:fader1 |
Expressions support a variety of data types and operators for performing calculations and manipulating data.
| Data Type | Description | Example |
|---|---|---|
| Number | Can be an integer or a floating-point number. | 10, 3.14 |
| String | A sequence of characters. | "hello", 'world' |
| Boolean | Can be either True or False. | True |
| Vector | A 2D, 3D, or 4D vector. | V2(1, 2) |
| Colour | An RGBA colour value. | Colour(1, 0, 0, 1) |
| Operator | Description | Example |
|---|---|---|
+ | Addition | 5 + 2 |
- | Subtraction | 5 - 2 |
* | Multiplication | 5 * 2 |
/ | Division | 5 / 2 |
== | Equal to | x == 5 |
!= | Not equal to | x != 5 |
< | Less than | x < 5 |
> | Greater than | x > 5 |
<= | Less or equal | x <= 5 |
>= | Greater or equal | x >= 5 |
and | Logical AND | x > 0 and y > 0 |
or | Logical OR | x > 0 or y > 0 |
not | Logical NOT | not z |
You can format strings within expressions using the format() function or the format:: prefix. This allows you to combine text with dynamic values.
The syntax for the format specifiers is %(flags)(width)(.precision)type.
Example with format() function:
format("Current time: %.2fs", time)
This will display the current time with two decimal places, followed by the “s” character (for seconds).
Example with format:: prefix:
format::"%.2f":time
This will achieve the same result as the format() function example.
Common Format Specifiers:
| Specifier | Description |
|---|---|
d | Signed integer decimal. |
f | Floating point decimal format. |
s | String (or any object, converted with str()). |
x | Signed integer hexadecimal. |
Variables are powerful tools for sharing values between multiple expressions and for breaking up complex expressions into smaller, more manageable parts.
Variables can be defined in several ways:
pi and e.uptime (the synchronized time across all servers).self (the current value of the property being controlled).myvar = sin(uptime / 20). This variable will only be available to layers that are higher in the composition stack and only while the layer defining it is active.You can create function variables that can be reused in multiple expressions. This is useful for abstracting complex logic. You can even pass parameters to these functions.
Example:
A function variable named maybe_override(value) with the expression if(osc:show.override, value, self) can be used on multiple layers. On one layer, you might use maybe_override(osc:show.field1), and on another, maybe_override(osc:show.field2).
You can programmatically set and manage expressions on layer properties using the Disguise Python API. Expressions are typically applied to the FieldSequence of a property.
| Task | Python |
|---|---|
| Set an expression on a layer property | layer = track.layers[0]seq = layer.findSequence("brightness")seq.setExpression("self * 0.5")This sets the brightness to half of its keyframed value. |
Use time to create an animation | layer = track.layers[0]seq = layer.findSequence("opacity")seq.setExpression("0.5 + 0.5 * math.sin(time * math.pi)")Creates a sine wave animation for the layer’s opacity. |
| Link one layer’s property to another | emitter_layer = track.layers[0]receiver_layer = track.layers[1]receiver_seq = receiver_layer.findSequence("brightness")receiver_seq.setExpression(f"module:{emitter_layer.name}.brightness")Links the brightness of receiver_layer to emitter_layer. Using an f-string is a clean way to build the expression. |
| Set an expression on a text layer | text_layer = track.layers[0]seq = text_layer.findSequence("text")seq.setExpression(f"'Current time: {time}'")Displays the current time on a text layer. |
| Use conditional logic in an expression | layer = track.layers[0]seq = layer.findSequence("brightness")seq.setExpression("if(time > 5, 1, 0)")Sets the brightness to 1 if the time is greater than 5 seconds, otherwise it is 0. |
| Clear an expression | layer = track.layers[0]seq = layer.findSequence("brightness")seq.setExpression("self")Resets the expression to its default, using the keyframed value. |
| Incorporate external data (e.g., OSC) | layer = track.layers[0]seq = layer.findSequence("brightness")seq.setExpression("self * (1 - osc:video.emergency_cut_out)")Multiplies brightness by an OSC input value. |
| Goal | Python |
|---|---|
| Create an ExpressionVariable device | device_name = "My Variables"device_path = "devices/{}".format(device_name)var_device = resourceManager.loadOrCreate(device_path, ExpressionVariablesDevice)device_manager = state.devicesif var_device not in device_manager.devices:device_manager.devices.append(var_device)Creates or loads a device, then ensures it is active in the Device Manager. |
| Add and configure a variable | var_container = var_device.container# Add a new, empty variablevar_container.variables.append(ExpressionVariable())# Get a reference to the new variablenew_var = var_container.variables[-1]# Now, set its propertiesnew_var.name = "my_variable_name"new_var.type = ExpressionVariable.FloatTypenew_var.defaultFloat = 5Adds and configures a new variable on the device. Other types include ExpressionVariable.StringType and ExpressionVariable.FunctionType. |
| Use the variable in another expression | layer = track.layers[0]seq = layer.findSequence("brightness")seq.setExpression("my_variable_name * 2")This will use the value of “my_variable_name” from the ExpressionVariable device and multiply it by 2. |
Here are a few more examples that combine the concepts covered in this guide to create more complex behaviors.
math.sinThis example uses a sine wave to create a smooth “breathing” effect for a layer’s brightness.
| Task | Python |
|---|---|
| Create a breathing animation | layer = track.layers[0]seq = layer.findSequence("brightness")seq.setExpression("0.5 + 0.5 * math.sin(time * 2)")This will cause the brightness to smoothly oscillate between 0 and 1. |
This example demonstrates how to control the RGB values of a Colour layer using three different OSC addresses.
| Goal | Python |
|---|---|
| Control RGB with OSC | color_layer = track.layers[0]color_layer.findSequence("red").setExpression("osc:color.red")color_layer.findSequence("green").setExpression("osc:color.green")color_layer.findSequence("blue").setExpression("osc:color.blue")This allows you to control the red, green, and blue channels of the color layer with separate OSC messages. |