Language Functions
A function takes the types its entry gives, and refuses others with a message
that lists what it takes. "Numbers" are :int, :uint, :float or :double
values, or vectors of one of them; "floats" are :float or :double values,
or vectors of them. Where a function goes component by component, a scalar
among vectors goes with each component. A function that takes complex numbers
says so, and one that GPUs compute of :float values only refuses doubles,
with a message that says so. Float pairs have the functions Numbers and
Precision lists.
(shader-documentation 'name) returns each one's description, and
doc/language.org, in clsl's repository, describes each in full.
The functions of textures and storage images are on Uniforms and Resources, derivatives and the stages' inputs on Definitions and Stages, and atomics and barriers on Shared Memory and Atomics.
Arithmetic
| Function | Takes and gives |
|---|---|
(+ number ...) |
the sum, 0 for none: numbers of one type, scalars among vectors; matrices of one type; complex numbers, a real among them of their parts' kind |
(- number ...) |
the first less the others, or with one, its negation; a :uint is not negated |
(* number ...) |
the product, 1 for none; as linear algebra multiplies, a matrix by a scalar of its components, a vector or a matrix, and a vector by a matrix |
(/ number ...) |
the first divided by the others, or with one, its reciprocal: floats, a matrix by a scalar of its components, complex numbers. Integers divide with truncate, floor, ceiling and round |
(1+ number), (1- number) |
number plus 1, or less 1 |
Integers computed by the GPU wrap: (+ i 1) of an :int that is 2147483647
is -2147483648. A matrix times a vector is the vector of its rows' dot
products with it, and a vector times a matrix that of its dot products with
the columns. Two or more arguments go two at a time, from the left. A complex
number is divided by Smith's method, which overflows no square.
Comparisons and predicates
| Function | Takes and gives |
|---|---|
(= number ...), (/= number ...) |
scalar numbers of one type, or complex numbers, a real among them taken as one, and a :bool |
(< number ...), (> ...), (<= ...), (>= ...) |
scalar reals of one type, one or more, and a :bool: (< 0 x 1) |
(not boolean) |
true if the :bool is false |
(zerop number), (plusp number), (minusp number) |
a scalar number, and a :bool; zerop takes a complex number too |
(evenp integer), (oddp integer) |
a scalar :int or :uint, and a :bool |
Vectors compare through every, some, notany, notevery and map:
(every #'= a b) is true if a and b are equal, and (map :bvec3 #'< a b) compares them component by component. Booleans combine with and, or
and not.
Division and rounding
| Function | Takes and gives |
|---|---|
(truncate number [divisor]), (floor ...), (ceiling ...), (round ...) |
two values, as Lisp's: the quotient, rounded toward zero, down, up, or to the nearest, halves to the even one, and the remainder, (- number (* quotient divisor)), of number's type. Floats give :int quotients; integers give their own type |
(ftruncate number [divisor]), (ffloor ...), (fceiling ...), (fround ...) |
the same, the quotient a float |
(mod number divisor) |
the remainder of floor, of divisor's sign |
(rem number divisor) |
the remainder of truncate, of number's sign |
The divisor is 1 by default, of number's type or a scalar of its
components'. A float quotient that no :int holds becomes the nearest one
that does, and a NaN 0. An integer divided by zero, or the most negative
:int by -1, gives the dividend and the remainder 0; a constant division by
zero is refused.
Conversions
| Function | Takes and gives |
|---|---|
(float number [prototype]) |
number as a float of prototype's kind, 1.0 for a :float and 1d0 for a :double, written in the code; or a vector, a matrix or a complex number of them. Without prototype, a float as it is, an integer as a :float, and a float pair as the :float nearest it |
(int integer), (uint integer) |
the :int, or :uint, with the bits of the integer, or a vector of them: one that fits stays as it is, and one that does not wraps |
(dfloat number) |
number as a float pair, or a vector of them: see Float pairs |
Floats become integers only through a function that names its rounding,
truncate, floor, ceiling or round: int and uint refuse them, and
the constructors of integer vectors take integers only.
Numbers
| Function | Takes and gives |
|---|---|
(abs number) |
the magnitude, component by component. The most negative :int is its own magnitude. Of a complex number, a float of its parts' kind, which overflows no square |
(signum number) |
-1, 0 or 1 of number's type; of a complex number, it divided by its magnitude, or itself if it is zero |
(min number ...), (max number ...) |
the least, or greatest, component by component |
(clamp number low high) |
(min (max number low) high), component by component |
(isqrt integer) |
the greatest integer whose square is at most integer, of its type; a negative :int computed as the shader runs gives 0 |
(decode-float float) |
three values, as cl:decode-float: the significand, from 0.5 below 1, or 0 for a zero; the exponent, an :int; and the sign, 1 or -1. Component by component, the exponents an :ivec of their shape. An infinity or a NaN gives its magnitude and the exponent 0 |
(float-sign float [magnitude]) |
a float of float's sign, by its sign bit, whose magnitude is magnitude's, 1 by default: (float-sign -0.0) is -1.0 |
(scale-float float integer) |
float times 2 to the :int integer, rounded once: an infinity where it is too large, and a zero where it is too small |
(float-nan-p float), (float-infinity-p float) |
true if the scalar :float or :double is a NaN, or an infinity; vectors test with some |
A denormal float, which some GPUs make 0, is decoded, and scaled to, as the GPU has it.
Complex numbers
| Function | Takes and gives |
|---|---|
(complex realpart [imagpart]) |
the complex number of the float parts, imagpart 0 by default: a :complex of :float values, a :dcomplex of :double values |
(realpart number), (imagpart number) |
the real or imaginary part; of a real, the real itself, or a zero of its type |
(conjugate number) |
the complex number with its imaginary part negated; a real as it is |
(phase number) |
the angle from the positive real axis, from -pi to pi, of a :complex; of a float, 0, or pi if its sign bit is set. A :dcomplex has none |
(cis radians) |
(complex (cos radians) (sin radians)) of a :float |
A complex number's arithmetic, abs, signum, sqrt, exp, log, expt
and its trigonometric and hyperbolic functions and their inverses are W.
Kahan's formulas, as SBCL computes them, with Lisp's branch cuts. A
:dcomplex has the arithmetic, abs, signum and sqrt. See Numbers and
Precision.
Bits
These are Common Lisp's functions of integers, on the 32 bits of :int and
:uint values, component by component for vectors.
| Function | Takes and gives |
|---|---|
(logand integer ...), (logior ...), (logxor ...), (logeqv ...) |
the bitwise and, inclusive or, exclusive or and equivalence; -1, 0, 0 and -1 for none |
(lognand a b), (lognor a b), (logandc1 a b), (logandc2 a b), (logorc1 a b), (logorc2 a b) |
as Common Lisp's: (logandc2 a b) is the and of a and the complement of b |
(lognot integer) |
the complement, (- -1 integer) |
(logtest a b) |
true if the scalar integers have a 1 bit in common; vectors test with some |
(logbitp index integer) |
true if bit index of the scalar integer is 1 |
(logcount integer) |
the number of 1 bits, or of 0 bits if it is negative: (logcount -1) is 0 |
(integer-length integer) |
the number of bits it needs, its sign left out: 0 for 0 and -1 |
(ash integer count) |
shifted left by count bits, or right by (- count), an :int's sign coming in from the left |
(ldb (byte size position) integer) |
the size bits from bit position up, as an integer of its type |
(ldb-test (byte size position) integer) |
true if any of those bits of the scalar integer is 1 |
(mask-field (byte size position) integer) |
integer with only those bits, where they are |
(dpb new (byte size position) integer) |
integer with those bits replaced by the size low bits of new |
(deposit-field new (byte size position) integer) |
integer with those bits replaced by those of new |
(float-bits float), (float-from-bits bits) |
the 32 bits of a :float, as a :uint, and the :float of 32 bits |
(add-carry a b), (subtract-borrow a b) |
two values: the sum, or difference, of the :uint values, wrapped, and its carry, or borrow, 1 or 0 |
(multiply-extended a b) |
two values: the low 32 bits of the 64-bit product of two :int or two :uint values, then its high 32 bits |
(find-lsb integer) |
the position of the lowest 1 bit, or -1 of its type |
(bitfield-reverse integer) |
the 32 bits in reverse order |
A byte, (byte size position), is written in the forms of ldb and its kin,
and is no value elsewhere. An :int's bits above bit 31 are copies of its
sign bit, as a negative integer's are in Lisp, and a :uint's are 0, so the
functions mean what they mean in Lisp, and their results wrap to 32 bits:
ash by 32 bits or more to the left gives 0, and to the right an :int's
sign bits; (ldb (byte 8 28) i) is 255 of the :int -1, and 15 of the
:uint 4294967295; logbitp past bit 31 tests an :int's sign bit. Numbers
written in the code are computed exactly: (ash 1 31) is 2147483648, which
fits a :uint and a :float, but not an :int.
Exponentials and trigonometry
These take :float values, and give values of the same type, component by
component. sqrt, inverse-sqrt, radians and degrees take :double
values too, as GPUs compute the others of :float values only. Each but
inverse-sqrt, radians and degrees takes a :complex, and sqrt a
:dcomplex, as Lisp's functions do, with Lisp's branch cuts.
| Function | Gives |
|---|---|
(sqrt number) |
the square root; a NaN for a negative float, and the principal root of a complex number |
(inverse-sqrt number) |
1 divided by the square root, in one instruction |
(exp number) |
e to the power number |
(expt base power) |
base to the power power. An integer written in the code as the power multiplies, so that it suits any number: (expt x 3) is (* x x x). 2 written as the base is the GPU's base-2 exponential. Otherwise both are :float values, and a negative base gives a NaN; or one is a :complex |
(log number [base]) |
the logarithm to base, e by default; 2 written as the base is the GPU's base-2 logarithm |
(radians degrees), (degrees radians) |
the angle in radians, or degrees, of floats of either kind |
(sin x), (cos x), (tan x) |
the sine, cosine and tangent |
(asin x), (acos x) |
the arc sine and arc cosine; a NaN outside -1 to 1 for a float |
(atan y [x]) |
the arc tangent of y, or of y/x with the quadrant from both signs; of one complex number only |
(sinh x), (cosh x), (tanh x), (asinh x), (acosh x), (atanh x) |
the hyperbolic functions and their inverses |
A power that is an integer computed by the code is refused: (expt x (float n)) raises to it as a float.
Interpolation
| Function | Takes and gives |
|---|---|
(mix a b weight) |
a blended toward b by weight, (+ (* a (- 1 weight)) (* b weight)); weight of their type or a scalar |
(smoothstep low high x) |
0 where x is at most low, 1 where it is at least high, and 3t² - 2t³ between; what it gives where low is not below high is the GPU's |
(fma a b c) |
(+ (* a b) c) of floats, rounded once where the GPU fuses it |
Geometry
These take vectors of :float or :double values; norm and distance
take scalars too.
| Function | Gives |
|---|---|
(dot a b) |
the dot product |
(cross a b) |
the cross product of two :vec3 or two :dvec3 values |
(norm vector) |
the Euclidean length; of a scalar, its magnitude. length counts components, as in Lisp |
(distance a b) |
the Euclidean distance between the points |
(normalize vector) |
vector scaled to a length of 1; what it gives for a zero vector is the GPU's |
(reflect incident normal) |
the direction incident is reflected to by a surface whose normal, of length 1, is normal |
(refract incident normal ratio) |
the direction incident is refracted to, ratio the ratio of the indices of refraction; a zero vector where it is reflected whole |
(face-forward normal incident reference) |
normal where reference faces against incident, and its negation otherwise |
Matrices
| Function | Takes and gives |
|---|---|
(transpose matrix) |
its rows as columns: a :mat2x3 gives a :mat3x2 |
(determinant matrix) |
the determinant of a square matrix |
(inverse matrix) |
the inverse of a square matrix; what it gives for one with no inverse is the GPU's |
(outer-product column row) |
the matrix product of column, as a column, and row, as a row |
(matrix-component-product a b) |
the matrices multiplied component by component, where * multiplies them as linear algebra does |
* multiplies matrices, + and - add and subtract them, and / divides
one by a scalar of its components. Matrices of doubles take the same
functions.
Packing
These pack floats into the bits of a :uint, the first in the low bits, and
unpack them.
| Function | Takes and gives |
|---|---|
(pack-unorm-4x8 vector), (pack-snorm-4x8 vector) |
a :vec4, each component clamped from 0 to 1, or -1 to 1, as 8 bits, (round (* c 255)) or (round (* c 127)) |
(pack-unorm-2x16 vector), (pack-snorm-2x16 vector) |
a :vec2, each component as 16 bits, (round (* c 65535)) or (round (* c 32767)) |
(pack-half-2x16 vector) |
a :vec2 as two IEEE floats of 16 bits |
(unpack-unorm-4x8 integer), (unpack-snorm-4x8 ...), (unpack-unorm-2x16 ...), (unpack-snorm-2x16 ...) |
the integers of the :uint divided by 255, 127, 65535 or 32767, the signed ones clamped from -1 to 1, as a :vec4 or a :vec2 |
(unpack-half-2x16 integer) |
the two 16-bit floats of the :uint, as a :vec2 |
(pack-double-2x32 words) |
the :double whose 64 bits are those of the :uvec2 words, the low 32 bits first |
(unpack-double-2x32 double) |
the 64 bits of the :double, as a :uvec2, the low 32 bits first |
A component halfway between two integers rounds as the GPU chooses, and so does one that no half-precision float holds.
Constructors
| Function | Takes |
|---|---|
(vec2 ...) to (vec4 ...), (dvec2 ...) to (dvec4 ...), (dfvec2 ...) to (dfvec4 ...), (ivec2 ...) to (ivec4 ...), (uvec2 ...) to (uvec4 ...), (bvec2 ...) to (bvec4 ...) |
its components, given as scalars and vectors of its components' type, in order: (vec4 position 0 1); one scalar for every component: (vec3 0); or a longer vector, whose first components it takes: (vec3 color4) |
(mat2 ...) to (mat4 ...), (mat2x3 ...) and the others, (dmat2 ...) and the others |
its components, column by column; its columns; one scalar for its diagonal, which is 0 elsewhere: (mat4 1) is the identity; or another matrix, whose components it takes where that matrix has them, and the identity's elsewhere: (mat3 model) is a :mat4's upper left |
A constructor takes its components' type only: (vec3 i 0 0) of an :int i
is refused, and (vec3 (float i) 0 0) is not; (dvec3 v) of a :vec3 is
refused, and (float v 1d0) is the :dvec3.
Components and elements
| Function | Takes and gives |
|---|---|
(x vector), (y vector), (z vector), (w vector) |
the first to the fourth component |
(swizzle vector :components) |
the components named, one or a vector of them |
(aref object index) |
the component of a vector, the column of a matrix, or the element of an array, at an :int or :uint index |
(length object) |
the number of components or elements, an integer written in the code; or of the elements of an array whose length is known only as the shader runs, a :uint |
(vector element ...) |
an array of the elements, (:array type n) |
(copy-seq sequence) |
a copy of the vector or array |
Each is a place, which setf, incf and decf assign. An index written in
the code is checked when the definition is evaluated; one computed reads zero
out of range, and an assignment there writes nothing.