Configuring effects

Ashley's avatar
Medal
Construct Team Founder
Published 3 Aug, 2017
1,358 words
~5-9 mins

The main configuration for an effect is set by additional effect-specific properties in addon.json. The additional properties used by effects are listed below.

category

The category the effect should appear in. This must be one of "blend", "color", "distortion", "normal-mapping", "other".

blends-background

Boolean indicating whether the effect blends with the background. Objects and layers can use effects that blend with the background, but layouts cannot.

cross-sampling

Boolean indicating whether a background-blending effect has inconsistent sampling of the background and foreground. A normal blending shader like Multiply will sample the background and foreground 1:1, so each foreground pixel samples only the background pixel it is rendered to. This is consistent sampling so cross-sampling should be false. However an effect that distorts the background, like Glass or a masking Warp effect, can sample different background pixels to the foreground pixel being rendered, so should set cross-sampling to true. This must be specified so the effect compositor can ensure the correct result is rendered when this happens.

preserves-opaqueness

Boolean indicating whether the effect preserves opaque pixels, i.e. every input pixel with an alpha of 1 is also output with an alpha of 1. This is true for most color-altering effects, but not for most distorting effects, since in some cases a previously opaque pixel will be distorted in to a transparent area of the texture. This information is not currently used, but is important for front-to-back rendering algorithms.

animated

Boolean indicating whether the effect is animated, i.e. changes over time using the seconds uniform. This is used to ensure Construct keeps redrawing the screen if an animated effect is visible.

must-predraw

Boolean indicating whether to force the pre-draw step. Sometimes Construct tries to optimise effect rendering by directly rendering an object with the shader applied. Setting this flag forces Construct to first render the object to an intermediate surface, which is necessary for some kinds of effect.

extend-box

Amount to extend the rendered box horizontally and vertically. Normally the effect is clipped to the object's bounding box, but some effects like Warp need to be able to render a short distance outside of that for the correct result. This property lets you extend the rendered box by a number of pixels. This property uses "horizontal" and "vertical" sub-properties, e.g. "extend-box": { "horizontal": 30, "vertical": 30 }

is-deprecated

Boolean to indicate a deprecated effect. This hides the effect from the Add effect dialog, but allows existing projects to continue using it. This allows an effect to be phased out without breaking projects.

parameters

An array of parameters that the effect uses. See the next section for more information.

Effect parameters

The parameters array in addon.json specifies a list of parameters that are passed to the shader as uniforms. These can be used to customise the appearance of the effect, and can also be changed at runtime. Each parameter is specified as an object with the following properties.

id

A string identifying this parameter.

c2id

The corresponding ID used by Construct 2 if this is not the same as the id. Note for color parameters, this can be a comma-separated list of the three parameter IDs previously used for the red, green and blue components, e.g. "red,green,blue".

type

The type of the effect parameter. This can be one of "float", "percent" or "color". Floats pass a simple number. Percent displays a percentage in the 0-100 range but passes a float in the 0-1 range to the shader. Color shows a color picker and passes a vec3 with components in the 0-1 range to the shader.

initial-value

The initial value of the shader uniform, in the format the shader uses it (i.e. 0-1 range for percent parameters). For color parameters, use a 3-element array, e.g. [1, 0, 0] for red.

uniform

The name of the corresponding uniform in the shader. The uniform must be declared in GLSL with this name. It can use whichever precision you want, but the uniform type must be vec3 for color parameters, otherwise float.

Shader uniforms

The shader is written in a GLSL (OpenGL Shading Language) fragment shader and interpreted by the browser's WebGL implementation. Note although Construct supports WebGL 2 where available, shaders should be written for WebGL 1 GLSL for compatibility with all systems. As with normal fragment shaders, the output is written to the special gl_FragColor variable.

The current foreground texture co-ordinate is provided in the special varying variable vTex. This is normally used to read the foreground texture, but it is actually optional (in case you want to write a shader that generates all of its output without reference to the foreground texture at all). All other uniforms are optional, and are documented below. The full uniform declaration is included with the recommended precision.

uniform lowp sampler2D samplerFront;

The foreground texture sampler, to be sampled at vTex.

uniform mediump vec2 srcStart;

uniform mediump vec2 srcEnd;

The current foreground rectangle being rendered, in texture co-ordinates. Note this is clamped as the object reaches the edge of the viewport. These are mainly useful for calculating the background sampling position.

uniform mediump vec2 srcOriginStart;

uniform mediump vec2 srcOriginEnd;

The current foreground source rectangle being rendered, in texture co-ordinates. This is not clamped, so can cover a rectangle that leaves the viewport. These are mainly useful for calculating the current sampling position relative to the object being rendered, without changing as the object clips against the viewport.

uniform mediump vec2 layoutStart;

uniform mediump vec2 layoutEnd;

The current foreground source rectangle being rendered, in layout co-ordinates. This allows the current fragment's position in the layout to be calculated.

uniform lowp sampler2D samplerBack;

The background texture sampler used for background-blending effects. The blends-background property in addon.json should also be set to true before using this. For the correct way to sample the background, see the next section.

uniform mediump vec2 destStart;

uniform mediump vec2 destEnd;

The current background rectangle being rendered to, in texture co-ordinates, for background-blending effects. For the correct way to sample the background, see the next section.

uniform mediump float seconds;

The time in seconds since the runtime started. This can be used for animated effects. The animated property in addon.json should be set to true.

uniform mediump vec2 pixelSize;

The size of a texel in the foreground texture in texture co-ordinates. This allows calculating distances in pixels rather than texture co-ordinates.

uniform mediump float layerScale;

The current layer scale as a factor (i.e. 1 is unscaled). This is useful to ensure effects scale according to zoom.

uniform mediump float layerAngle;

The current layer angle in radians.

Useful shader calculations

Some common calculations done with the available uniforms are listed below.

To sample the foreground pixel:

	lowp vec4 front = texture2D(samplerFront, vTex);

To sample an adjacent pixel, offset by the pixel size:

	// sample next pixel to the right
	lowp vec4 next = texture2D(samplerFront, vTex + vec2(pixelSize.x, 0.0));

To calculate the position to sample the background, find the normalised position n of vTex in the foreground rectangle, and apply that to the background rectangle:

	mediump vec2 n = (vTex - srcStart) / (srcEnd - srcStart);
	lowp vec4 back = texture2D(samplerBack, mix(destStart, destEnd, n));

To calculate the current texture co-ordinate relative to the object being rendered, without being affected by clipping at the edge of the viewport, use the original source rectangle:

	mediump vec2 srcOriginSize = srcOriginEnd - srcOriginStart;
	mediump vec2 n = ((vTex - srcOriginStart) / srcOriginSize);

To calculate the current layout co-ordinates being rendered, add an extra step to interpolate n across the layout rectangle:

	mediump vec2 srcOriginSize = srcOriginEnd - srcOriginStart;
	mediump vec2 n = ((vTex - srcOriginStart) / srcOriginSize);
	mediump vec2 l = mix(layoutStart, layoutEnd, n);

Construct renders using premultiplied alpha. Often it is convenient to modify the RGB components without premultiplication. To do this, divide by alpha to unpremultiply the color, but be sure not to divide by zero.

	lowp vec4 front = texture2D(samplerFront, vTex);
	lowp float a = front.a;
	
	// unpremultiply
	if (a != 0.0)
		front.rgb /= a;
	
	// ...modify unpremultiplied front color...
	
	// premultiply again
	front.rgb *= a;