fennec
Loading...
Searching...
No Matches
Common

The Common Functions defined in the OpenGL 4.6 Shading Language Specification.

Common

Sign Functions

Syntax Description

genIType abs(genIType x)
genFType abs(genFType x)
genDType abs(genDType x)

Returns
\(x\) if \(x \ge 0\), otherwise it returns \(-x\).

We can express this as,

\(\text{abs}(x)=\left|x\right|\).

Parameters
xinput value

genIType sign(genIType x)
genFType sign(genFType x)
genDType sign(genDType x)

Returns
\(1\) if \(x > 0\), \(0\) if \(x = 0\), or \(-1\) if \(x<0\)

We can express this as,

\(\text{sign}(x) = \text{sgn}(x) = \left\{\begin{array}{lr} -1 & x < 0, \\ 0 & x = 0, \\ 1 & x > 0.\end{array}\right.\)

Parameters
xinput value

Rounding Functions

Syntax Description

genFType floor(genFType x)
genDType floor(genDType x)

Returns
a value equal to the nearest integer that is less than or equal to \(x\)

We can express this as,

\(\text{floor}(x)=\lfloor x\rfloor\)

Parameters
xinput value

genFType ceil(genFType x)
genDType ceil(genDType x)

Returns
a value equal to the nearest integer that is greater than or equal to \(x\)

We can express this as,

\(\text{ceil}(x)=\lceil{x}\rceil\)

Parameters
xinput value

genFType round(genFType x)
genDType round(genDType x)

Returns
a value equal to the nearest integer.

In C++, a fractional part of \(0.5\) will always round up.

We can express this as,

\(\text{round}(x) = \text{sgn}(x) \cdot \lfloor \left| x \right| + 0.5 \rfloor\)

Parameters
xinput value

genFType roundEven(genFType x)
genDType roundEven(genDType x)

Returns
a value equal to the nearest integer.

In C++, a fractional part of \(0.5\) will always round to the nearest even integer.

We can express this as,

\(\text{roundEven}() = \begin{cases}\lfloor{x}\rfloor + \text{mod}(\lfloor{x}\rfloor, 2.0) & \text{fract}(x) = 0.5, \\ \text{round}(x) \end{cases}\)

Parameters
xinput value

genFType trunc(genFType x)
genDType trunc(genDType x)

Returns
a value equal to the nearest integer that is less than or equal to \(x\)

We can express this as,

\(\text{trunc}(x) = \text{sgn}(x) \cdot \lceil \left| x \right| - 0.5 \rceil\)

Parameters
xinput value

Decimal-Point Functions

Syntax Description

genFType fract(genFType x)
genDType fract(genDType x)

Returns
\(x - \text{floor}(x)\)

We can express this as,

\(\text{fract}(x)=x-\text{floor}\)

Parameters
xinput value

genFType mod(genFType x, float y)
genFType mod(genFType x, genFType y)
genDType mod(genDType x, double y)
genDType mod(genDType x, genDType y)

Returns
\(x-y\cdot\text{floor}(x/y)\)

We can express this as,

\(\text{fract}(x)=x-\text{floor}(\frac{x}{y})\)

Parameters
xdividend
ydivisor

genFType modf(genFType x, out genFType i)
genDType modf(genDType x, out genDType i)

Returns
the fractional part of \(x\) and stores the integral part in \(i\).

We can express this as,

\(\text{modf}(x) = \text{trunc}(x),\, i := \text{fract}(x)\)

Parameters
xinput value
iintegral out

genBType isnan(genFType x)
genBType isnan(genDType x)

Returns
true if \(x\) holds a NaN. Returns false otherwise.

\(NaN\) is a concept unique to computing. It strictly means, and more specifically, floating point values can only represent real numbers. This is why some functions, like sqrt(), return \(NaN\) when an expression would return a value in a different coordinate space. There are other cases, such as \(\frac{1}{x}\), where \(x=0\) is undefined, and respectively the return value is also \(NaN\).

To learn more, see IEEE 754

Parameters
xinput value

genBType isinf(genFType x)
genBType isinf(genDType x)

Returns
true if \(x\) holds a positive or negative infinity. Returns false otherwise.

\(\inf\), or \(\infty\), is used to express any function that is boundless, endless, or larger than any natural number. This function has applications in Set Theory and Mathematical Analysis.

Parameters
xinput value

genFType frexp(genFType x, out genIType exp)
genDType frexp(genDType x, out genIType exp)

Returns
The significand of the expression.

The significand is returned by the function and the exponent is returned in the parameter \(exp\). For a floating-point value of zero, the significand and exponent are both zero. If an implementation supports signed zero, an input value of minus zero should return a significand of minus zero. For a floating-point value that is an infinity or is not a number, the results are undefined. If the input \(x\) is a vector, this operation is performed in a component-wise manner; the value returned by the function and the value written to \(exp\) are vectors with the same number of components as \(x\).

Parameters
xThe floating-point value to split
expThe variable to store the exponent in

genFType ldexp(genFType x, genIType exp)
genDType ldexp(genDType x, genIType exp)

Returns
\({x}\cdot{2^{exp}}\)

Builds a floating-point number from x and the corresponding integral exponent of two in exp, returning: \({x}\cdot{2^{exp}}\). If this product is too large to be represented in the floating-point type, the result is undefined. If exp is greater than +128 (single-precision) or +1024 (double-precision), the value returned is undefined. If exp is less than -126 (single-precision) or -1022 (double-precision), the value returned may be flushed to zero. Additionally, splitting the value into a significand and exponent using frexp() and then reconstructing a floating-point value using ldexp() should yield the original input for zero and all finite non-subnormal values. If the input x is a vector, this operation is performed in a component-wise manner; the value passed in exp and returned by the function are vectors with the same number of components as x.

Parameters
xThe significand
expThe exponent

Bit Conversion

Syntax Description

genIType floatBitsToInt(genType value)
genUType floatBitsToUint(genType value)

Returns
a signed or unsigned integer value representing the encoding of a floating-point value. The float value's bit-level representation is preserved.

we can express this in set theory, i.e.

let \(B\) be a set, such that, \(B=\left\lbrace{b_{0},...b_{32}}\right\rbrace\) and \(b_{i} \in S\) where \(S=\left\lbrace{0, 1}\right\rbrace\)
let \(m_B=\frac{b_{0}}{2^1}+\cdots +\frac{b_{i}}{2^{i+1}}+\cdots +\frac{b_{22}}{2^{23}}\begin{cases}1&\end{cases}\)
let \(p_B=b_{23}\cdot 2^0+\cdots +b_i\cdot 2^{i-23}+\cdots +b_{30}\cdot 2^7-127\)
let \(s_B=\begin{cases}-1,&b_{31}=1 \\ 1\end{cases}\)

then, \(x_B=s_B m_B 2^{p_B}\)
and, \(i_B=-b_{31} 2^{31}+\sum_{i=0}^{30}{a_i 2^i}\)
and, \(u_B=\sum_{i=0}^{31}{a_i 2^i}\)

Parameters
xvalue to convert

genFType intBitsToFloat(genIType value)
genFType uintBitsToFloat(genUType value)

Returns
a floating-point value corresponding to a signed or unsigned integer encoding of a floating-point value.

we can express this in set theory, i.e.

let \(B\) be a set, such that, \(B=\left\lbrace{b_{0},...b_{32}}\right\rbrace\) and \(b_{i} \in S\) where \(S=\left\lbrace{0, 1}\right\rbrace\)
let \(m_B=\frac{b_{0}}{2^1}+\cdots +\frac{b_{i}}{2^{i+1}}+\cdots +\frac{b_{22}}{2^{23}}\begin{cases}1&\end{cases}\)
let \(p_B=b_{23}\cdot 2^0+\cdots +b_i\cdot 2^{i-23}+\cdots +b_{30}\cdot 2^7-127\)
let \(s_B=\begin{cases}-1,&b_{31}=1 \\ 1\end{cases}\)

then, \(x_B=s_B m_B 2^{p_B}\)
and, \(i_B=-b_{31} 2^31+\sum_{i=0}^{30}{a_i 2^i}\)
and, \(u_B=\sum_{i=0}^{31}{a_i 2^i}\)

Parameters
xvalue to convert

Comparison Functions

Syntax

Description


genFType min(genFType x, float y)
genFType min(genFType x, genFType y)
genDType min(genDType x, double y)
genDType min(genDType x, genDType y)
genIType min(genDType x, int y)
genIType min(genIType x, genIType y)
genUType min(genUType x, uint y)
genUType min(genUType x, genUType y)

Returns
\(y\) if \(x<y\), otherwise it returns \(x\)

We can express this as,

\(\text{min}(x, y)=\begin{cases}y, & y < x \\ x\end{cases}\)

Parameters
xinput value \(x\)
yinput value \(y\)

genFType max(genFType x, float y)
genFType max(genFType x, genFType y)
genDType max(genDType x, double y)
genDType max(genDType x, genDType y)
genIType max(genDType x, int y)
genIType max(genIType x, genIType y)
genUType max(genUType x, uint y)
genUType max(genUType x, genUType y)

Returns
\(y\) if \(y<x\), otherwise it returns \(x\)

We can express this as,

\(\text{max}(x, y)=\begin{cases}y, & x < y \\ x\end{cases}\)

Parameters
xfirst input value
ysecond input value

genFType clamp(genFType x, float minVal, float maxVal)
genFType clamp(genFType x, genFType minVal, genFType maxVal)
genDType clamp(genDType x, double minVal, double maxVal)
genDType clamp(genDType x, genDType minVal, genDType maxVal)
genIType clamp(genDType x, int minVal, int maxVal)
genIType clamp(genIType x, genIType minVal, genIType maxVal)
genUType clamp(genUType x, genUType minVal, uint maxVal)
genUType clamp(genUType x, genUType minVal, genUType maxVal)

Returns
\(\text{min}(\text{max}(x, minVal), maxVal)\). Results are undefined if \(minVal > maxVal\)

We can express this as,

\(\text{clamp}(x, min, max)=\begin{cases}min, & x < min \\ x \\ max, & x > max\end{cases}\)

Parameters
xinput value
minValminimum value
maxValmaximum value

Curve Functions

Syntax Description

step(float edge, genFType x)
step(genFType edge, genFType x)
step(double edge, genDType x)
step(genFType edge, genDType x)

Returns
\(0.0\) if \(x<edge\), otherwise, it returns \(1.0\)

We can express this as,

\(\text{step}(edge, x)=\begin{cases}0.0 & x < edge \\ 1.0 \end{cases}\)

Parameters
edgeThe \(x\) coordinate of the discontinuity
xThe coordinate of the sample location

smoothstep(float edge0, float edge1, genFType x)
smoothstep(genFType edge0, genFType edge1, genFType x)
smoothstep(double edge0, double edge1, genDType x)
smoothstep(genFType edge0, genFType edge1, genDType x)

Returns
\(0.0\) if \(x\le edge0\) and \(1.0\) if \(x\ge edge1\), and performs smooth Hermite interpolation between \(0\) and \(1\) when \(edge0<x<edge1\).

This is useful in cases where you would want a threshold function with a smooth transition.

This is equivalent to:

genFType t;
t = clamp((x - edge0) / (edge1 - edge0), 0, 1);
return t * t * (3 - 2 * t);


Results are undefined if \(edge0\ge edge1\).

We can express this as,

\(\text{smoothstep}(e_0, e_1, x)=\begin{cases}0, & {x}\le{e_0} \\ 3{\frac{x-e_0}{e_1-e_0}}^{2} - 2{\frac{x-e_0}{e_1-e_0}}^{3}, & {e_0}\le{x}\le{e_1} \\ 1, & {1}\le{e_x}\end{cases}\)

Parameters
edge0\(x\) value where the function returns \(0.0\)
edge1\(x\) value where the function returns \(1.0\)
x\(x\) coordinate input

mix(genFType x, genFType y, float a)
mix(genFType x, genFType y, genFType a)
mix(genDType x, genDType y, double a)
mix(genDType x, genDType y, genDType a)

Returns
the linear blend of \(x\) and \(y\), i.e., \(x \cdot (1-a) + y \cdot a\)

We can express this as,

\(\text{mix}(x, y, a)=x+a \cdot (y - x)\)

The reason for the difference between the mathematical definition and the glsl definition is due to floating-point precision errors. Multiplying \(x\) and \(y\) separately preserves their precision before the addition happens.

Parameters
xFirst value
ySecond value
aInterpolant

mix(genBType x, genBType y, genBType a)
mix(genIType x, genIType y, genBType a)
mix(genUType x, genUType y, genBType a)
mix(genFType x, genFType y, genBType a)
mix(genDType x, genDType y, genBType a)

Returns
the linear blend of \(x\) and \(y\), i.e., \(x \cdot (1-a) + y \cdot a\)

We can express this as,

\(\text{mix}(x, y, a)=x+a \cdot (y - x)\)

The reason for the difference between the mathematical definition and the glsl definition is due to floating-point precision errors. Multiplying \(x\) and \(y\) separately preserves their precision before the addition happens.

Parameters
xFirst value
ySecond value
aInterpolant