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 8 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 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.

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:



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 between -1.0 and 1.0. You can normalize them later using dedicated button.

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:



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) 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:
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", WRAP, FILTER]

where format is one of: png, jpg/jpeg, bmp,
and where 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

and 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, samplerCube
examples:

uniform sampler2D Tex; //! texture["debug1.png"]
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", filter: GL_NEAREST]
uniform sampler2D Tex; //! texture["debug1.png", wrap: GL_CLAMP_TO_EDGE, filter: GL_NEAREST]
uniform sampler2D Tex; //! texture["debug1.png", 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]

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