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 10 types of the Uniform Controls possible to use in Fragx shaders:


checkbox

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.

format:

checkbox[true]
checkbox[false]

supported types: bool
examples:

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

widgets:



color

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.

format:

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
examples:

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]

widgets:



combobox

Combobox Uniform Control is used for enumerations. 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.

format:

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
examples:

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

widgets:



depthmap

Depthmap Uniform Control allows to access Microsoft Kinect sensor input in form of a depthmap. Support for this Uniform Control is experimental and was tested only on Mac OS. On other Operating Systems might not work.

format:

depthmap[]

supported types: sampler2D
examples:

uniform vec3 iResolution;
uniform sampler2D DepthTex; //! depthmap[]

void main() {
        vec2 uv = gl_FragCoord.xy / iResolution.xy;
        gl_FragColor = texture(DepthTex, uv);
}

widgets:



direction

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.

format:

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
examples:

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)]

widgets:



keyboard

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.

format:

keyboard[]

supported types: sampler2D
examples:

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);
}

widgets:



music

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.

format:

music[]
music["path/to/music.mp3"]

supported types: sampler2D
examples:

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

widgets:



rotation

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.

format:

// 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]
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
examples:

// 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]

widgets:



slider

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.

format:

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
examples:

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)]

widgets:



texture

With Texture Uniform Controls you can fed your shaders with arbitrary images. You can use 2D textures (with sampler2D uniforms), 3D textures (with sampler3D 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).

3D case is similar, but it is limited to files in Shadertoy's '.bin' format.

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:
mountains_0.png
mountains_1.png
mountains_2.png
mountains_3.png
mountains_4.png
mountains_5.png
You need to put only the first one as an argument to texture UC:
texture["path/to/mountains_0.png"]

format:

texture["path/to/texture.format"]
texture["path/to/texture.format", mipmap: MIP_VALUE]
texture["path/to/texture.format", aniso: ANISO_VALUE]
texture["path/to/texture.format", vflip: VFLIP_VALUE]
texture["path/to/texture.format", WRAP]
texture["path/to/texture.format", FILTER]

// All parameters. Order (apart the first one) doesn't matter.
texture["path/to/texture.format", WRAP, FILTER, mipmap: MIP_VALUE, aniso: ANISO_VALUE, vflip: VFLIP_VALUE]

where format is one of: png, jpg/jpeg, bmp, hdr;

MIP_VALUE is a boolean value: true or false. If there is no explicit mipmap parameter the default ones are: true - for sampler2D and sampler3D, false - for samplerCube.

ANISO_VALUE is a boolean value: true or false. The aniso parameter turns on or off anisotropic filtering. Default is false.

VFLIP_VALUE is a boolean value: true or false. The vflip parameter can filp a texture vertically. Default is false.

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:
wrap: WRAP_MODE


FILTER is one or couple of:

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


WRAP_MODE is one of:

GL_REPEAT
GL_CLAMP_TO_EDGE
GL_CLAMP_TO_BORDER
GL_MIRRORED_REPEAT
// default is GL_REPEAT


FILTER_MODE is one of:

GL_LINEAR
GL_NEAREST
// default is GL_LINEAR


supported types: sampler2D, sampler3D, samplerCube

examples:

uniform sampler2D Tex; //! texture[]
uniform sampler2D Tex; //! texture["debug1.png"]

// Mipmapping
uniform sampler2D Tex; //! texture["debug1.png", mipmap: true]
uniform sampler2D Tex; //! texture["debug1.png", mipmap: false]

// Anisotropic filtering
uniform sampler2D Tex; //! texture["debug1.png", aniso: true]
uniform sampler2D Tex; //! texture["debug1.png", aniso: false]

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", aniso: 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", aniso: 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]

// Cube map sampler
uniform samplerCube CubemapTex; //! texture["Shadertoy/res/cube04_0.png"]
uniform samplerCube CubemapTex; //! texture["Shadertoy/res/cube04_0.png", wrap: GL_CLAMP_TO_EDGE, filter: GL_NEAREST]

// 3D texture sampler
uniform sampler3D Tex3D; //! texture["Shadertoy/res/gray_noise_3d.bin"]
uniform sampler3D Tex3D; //! texture["Shadertoy/res/rgba_noise_3d.bin", mipmap: false]
uniform sampler3D Tex3D; //! texture["Shadertoy/res/gray_noise_3d.bin", wrap: GL_CLAMP_TO_EDGE, filter: GL_NEAREST]

widgets:



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);
}