Uniform Controls

Uniform Controls (UCs) are a way to interact with shaders. Using them you can change shader parameters and behavior. The idea is simple: every parameter, that you want to be able to change during shader execution, should be declared as uniform variable and annotated, in comments, by special command that describes control type, its range and initial value. Each UC has corresponding graphical widget/control/component in the Uniform Controls View that can by modified by the user.

Not all UCs can be used for every uniform variable. This document describes each of the Uniform Controls, their parameters and supported variable types.

Control types

Currently there are 9 types of the Uniform Controls possible to use in Fragx shaders:


Checkbox Uniform Controls are used only for bool uniform variables. They simply set true or false to the uniform, depending on the state of Checkbox widget.



supported types: bool

uniform bool SomeFlag; //! checkbox[true]
uniform bool SomeOtherFlag; //! checkbox[false]



Color Uniform Controls, as the name suggests, are used for setting color to uniforms. They can be used with vec3 or vec4 types, representing RGB or RGBA values, respectively.


color[R, G, B]
color[R, G, B, A]
color[MinA, A, MaxA, R, G, B]

where R, G, B, A, MinA, MaxA are float numbers between 0.0 and 1.0.

supported types: vec3, vec4

uniform vec3 ColorRGB; //! color[0.393, 0.871, 0.114]
uniform vec4 ColorRGBA; //! color[0.255, 0.506, 0.91, 0.27]
uniform vec4 OtherRGBA; //! color[0.2, 0.59, 0.6, 0.651, 1.0, 0.797]



Combobox Uniform Control is used for enumarations. It is presented as String dropdown list but essentially it is mapped to integer fields, therefore it can be used as replacement for integer slider UC. Value of this UC is an index of selected String value.


combobox[SelectedIndex, "Value1", "Value2", ..., "ValueN"]

where SelectedIndex is of type int and must be between 0 and N - 1 (Remember: index always starts from 0). "Value1", "Value2", ..., "ValueN" are String values. You must provide at least one such value.

supported types: int

uniform int LightingModel; //! combobox[1, "Phong", "Cook-Torrance", "Oren-Nayar"]
uniform int Shape; //! combobox[4, "Cone", "Sphere", "Torus", "Box", "Teapot"]



Direction Uniform Controls are used for setting vec3 values, that represent directional vectors. They have special button for normalization and additional popup widget with interactive "arrow" (cone to be exact). You can drag this arrow to change its direction, which in consequence, will accordingly change controlled vec3 value.


direction[X, Y]
direction[X, Y, Z]

// or with optional round brackets, suggesting that argument is one vector value:

direction[(X, Y)]
direction[(X, Y, Z)]

where X, Y, Z are float numbers. Components of the direction vector will be automatically renormalized during shader startup, so you don't need to give normalized vector.

supported types: vec2, vec3

uniform vec2 Direction; //! direction[1.0, 0.0]
uniform vec3 Direction; //! direction[1.0, 0.0, 0.0]

// or with optional round brackets, suggesting that argument is one vector value:

uniform vec2 Direction; //! direction[(1.0, 0.0)]
uniform vec3 Direction; //! direction[(1.0, 0.0, 0.0)]



Keyboard Uniform Control can be used for reading a keyboard state (if a key is pressed or toggled). It is exact copy of the Shadertoy's keyboard input. The keyboard state is kept in a texture with dimensions 256 x 2. Each row represents the same set of 256 characters. Index (from 0 to 255) of a texel in a row equals to a key code which the texel represents. Key codes are compatible with JavaScript and the list of most notable ones can be found here.

Each texel has only one component - R - which can have only one of the two values: 0.0 (off), 1.0 (on). The Lower row (the one sampled with y <= 0.5) of the texture keeps track of the pressed (1.0) / released (0.0) key state. The upper row (the one sampled with y > 0.5) keeps track of whether a key is toggled or not.

Keyboard input is gathered only when the Viewport View is focused.



supported types: sampler2D

uniform sampler2D MyKeyboardTex; //! keyboard[]

bool isPressed(float keyCode) {
        keyCode = (keyCode + 0.5) / 256.0;
        vec2 uv = vec2(keyCode, 0.25);
        float key = texture2D(MyKeyboardTex, uv).r;

        return key > 0.0;

bool isToggled(float keyCode) {
        keyCode = (keyCode + 0.5) / 256.0;
        vec2 uv = vec2(keyCode, 0.75);
        float key = texture2D(MyKeyboardTex, uv).r;

        return key > 0.0;

#define KEY_A 65.0
#define KEY_1 49.0
#define KEY_RIGHT_ARROW 39.0

void main() {
        vec3 col = vec3(0.0);
        if (isToggled(KEY_A)) {
                col.r = 1.0;
        if (isPressed(KEY_1)) {
                col.g = 1.0;
        if (!isPressed(KEY_RIGHT_ARROW)) {
                col.b = 1.0;
        gl_FragColor = vec4(col, 1.0);



Music Uniform Control represents special type of texture. Texture that is generated in every frame from played audio track. It is two texels high and N texels wide. (The value of N isn't relevant but usually it is 1024 or 2048). First row of texels represents a frequency spectrum, and the second one represents a waveform. It is analogous to Shadertoy's audio input channel. Only one music UC can be used in a single shader.



supported types: sampler2D

uniform sampler2D Music; //! music[]
uniform sampler2D Music; //! music["resources/mytrack.mp3"]



Rotation Uniform Controls are helpful when one need to control rotation or orientation of some objects in a scene. They can be used for 2D and 3D rotations.

For 2D case, they can be mapped to float (representing angle) or mat2 (representing rotation matrix) uniforms.

For 3D case, they can be used with vec3 uniforms or with mat3/mat4 uniforms. With vec3 they set Euler's angles to corresponding vector components. With mat3/mat4 they output standard 3x3/4x4 rotation matrix.

The input of rotation UCs can be expressed in radians (default) or in degrees (with setting "input" parameter to "degrees"). Output is always in radians (in case of float, vec3; matrices don't have angle components).

Values of rotation components can be controlled by sliders/spinners or by special popup widget with interactive circle/sphere. Circle/sphere orientation can be changed by dragging a mouse.


// For 3D case:
rotation[Pitch, Yaw, Roll]
rotation[Pitch, Yaw, Roll, input: degrees]
rotation[Pitch, Yaw, Roll, input: radians]

// or with optional round brackets, suggesting that the first argument is one vector value:

rotation[(Pitch, Yaw, Roll)]
rotation[(Pitch, Yaw, Roll), input: degrees]
rotation[(Pitch, Yaw, Roll), input: radians]

// For 2D case:
rotation[Angle, input: degrees]
rotation[Angle, input: radians]

where Pitch, Yaw, Roll are Euler angles represented by float numbers. Angle is a 2D rotation angle, also of float type. Default input type units are radians.

supported types: float, vec3, mat2, mat3, mat4

// 3D case:

// default in radians:
uniform vec3 RotationRadVec; //! rotation[3.14, 1.62, 0.44]
uniform mat3 RotationRadMat3; //! rotation[3.14, 1.62, 0.44]
uniform mat4 RotationRadMat4; //! rotation[3.14, 1.62, 0.44]
// in degrees:
uniform vec3 RotationVec; //! rotation[45, 10, 200, input: degrees]
uniform mat3 RotationMat3; //! rotation[45, 10, 200, input: degrees]
uniform mat4 RotationMat4; //! rotation[45, 10, 200, input: degrees]

//2D case:

// default in radians:
uniform float RotationFloat; //! rotation[3.14]
uniform mat2 RotationMat2; //! rotation[3.14]
// in degrees:
uniform float RotationFloat; //! rotation[45, input: degrees]
uniform mat2 RotationMat2; //! rotation[45, input: degrees]



Slider Uniform Control is most general type of UC. It can represent set of discrete states (int uniform), rotation/direction (vec2/vec3 uniform), or just simple 1,2,3,4-directional range of values. It is probably the one you will use the most.


slider[MinValue, Value, MaxValue]

where MinValue, Value, MaxValue are of one of the following types: int, uint, float, double, vec2, vec3, vec4. Vector values are represented by float numbers separated by comma, and enclosed in brackets. For example "vec2(1.5, 2.4)" is represented by "(1.5, 2.4)".

supported types: int, uint, float, double, vec2, vec3, vec4

uniform int IntSlider; //! slider[-5, 1, 7]
uniform uint UintSlider; //! slider[0, 1, 7]
uniform float FloatSlider; //! slider[-5, 1, 7]
uniform vec2 Vec2Slider; //! slider[(-5,-5), (1,1), (7,7)]
uniform vec3 Vec3Slider; //! slider[(-5,-5,-5), (1,1,1), (7,7,7)]
uniform vec4 Vec4Slider; //! slider[(-5,-5,-5,-5), (1,1,1,1), (7,7,7,7)]



With Texture Uniform Controls you can fed your shaders with arbitrary images. You can use 2D textures (with sampler2D uniforms) or Cubemap textures (with samplerCube uniforms). 2D case is trivial - you just need to put image path as an argument to texture UC (or choose image file from filechooser, which is equivalent).

In case of Cubemap you need 6 images with the same name but with different suffix. Suffix consists of underscore and image number. For example if your Cubemap is made up from 6 images in png format and you have chosen common name for them to be "mountains" you should have following files:
You need to put only the first one as an argument to texture UC:


texture["path/to/texture.format", mipmap: MIP_VALUE]
texture["path/to/texture.format", mipmap: MIP_VALUE, WRAP, FILTER]

where format is one of: png, jpg/jpeg, bmp;
MIP_VALUE is a boolean value: true or false. If there is no explicit mipmap parameter the default ones are: true - for sampler2D, false - for samplerCube.
WRAP is one or couple of:

// wrap in s direction:
wrap_s: WRAP_MODE
// wrap in t direction:
wrap_t: WRAP_MODE
// wrap in both s and t directions:

and FILTER is one or couple of:

// minification filter:
min_filter: FILTER_MODE
// magnification filter:
mag_filter: FILTER_MODE
// both minification and magnification filter:

WRAP_MODE is one of:

// default is GL_REPEAT

FILTER_MODE is one of:

// default is GL_LINEAR

supported types: sampler2D, samplerCube

uniform sampler2D Tex; //! texture["debug1.png"]
uniform sampler2D Tex; //! texture["debug1.png", mipmap: true]
uniform sampler2D Tex; //! texture["debug1.png", mipmap: false]
uniform samplerCube CubemapTex; //! texture["Shadertoy/res/cube04_0.png"]

uniform sampler2D Tex; //! texture["debug1.png", wrap: GL_CLAMP_TO_EDGE]
uniform sampler2D Tex; //! texture["debug1.png", mipmap: true, filter: GL_NEAREST]
uniform sampler2D Tex; //! texture["debug1.png", wrap: GL_CLAMP_TO_EDGE, filter: GL_NEAREST]
uniform sampler2D Tex; //! texture["debug1.png", mipmap: false, wrap_s: GL_CLAMP_TO_EDGE, wrap_t: GL_REPEAT, filter: GL_NEAREST]
uniform sampler2D Tex; //! texture["debug1.png", wrap_s: GL_CLAMP_TO_EDGE, wrap_t: GL_REPEAT, min_filter: GL_NEAREST, mag_filter: GL_LINEAR]


Uniform comments

Comments (either single- or multi-line) that are declared directly above uniform variables are recognized by Synthclipse as descriptions. They are shown as tool tips in Uniform Controls View after hovering mouse over these variables.

// Example of the uniform descriptions.

// This is a single-line description of Gamman uniform
uniform float Gamma; //! slider[0.1, 2.2, 10]

 * This is
 * a multiline description
 * of Frequency uniform.
uniform float Frequency; //! slider[-10, 2, 100]

Inactive uniforms

Inactive uniforms are those uniform variables that you have declared but never used. Even if a variable is used in some function but this function is never called, then the variable is also considered as inactive.

Inactive Uniform Controls are disabled in the Uniform Controls View, since their modification would not affect shader execution in any way.

// Example of inactive uniforms.

// this uniform is never used:
uniform bool WithGamma; //! checkbox[true]

// this uniform is also never used, since function "func"
// is never called.
uniform float Gamma; //! slider[0.1, 2.2, 10]
uniform float Frequency; //! slider[-10, 2, 100]

float func(float f) {
        return Gamma * f;

void main() {
        vec2 uv = gl_FragCoord.xy / iResolution.xy;
        vec3 col = vec3(uv, 0.5 + 0.5 * sin(uv.x * uv.y * Frequency));

        gl_FragColor = vec4(col, 1.0);