There are only a few test oscillators implemented for now, with plans to add many more. One key conceptual difference between SuperCollider audio oscillators and Scintillator video oscillators to bear in mind is that video signals are constrained to values between [0, 1]
, unlike audio signals, which operate normally between [-1, 1]
.
VGen | Rates | Dimensions | Description |
VSinOsc.fr(freq, phas, mul, add) | frame, shape, pixel |
input | output | 1, 1, 1, 1 | 1 | 2, 2, 2, 2 | 2 | 3, 3, 3, 3 | 3 | 4, 4, 4, 4 | 4 |
| Piecewise sinusodal oscillator, analogous to SinOsc |
VSaw.fr(freq, phas, mul, add) | frame, shape, pixel |
input | output | 1, 1, 1, 1 | 1 | 2, 2, 2, 2 | 2 | 3, 3, 3, 3 | 3 | 4, 4, 4, 4 | 4 |
| Piecewise sawtooth oscillator, analogous to LFSaw |
VGens for reading from ScinImageBuffer objects.
VGen | Rates | Dimensions | Description |
VSampler.pr(image, pos) | frame, shape, pixel |
| Samples the provided imageBuffer at pos and returns the 4D color signal as (red, green, blue, alpha) |
VTexPos.fr() | shape, pixel |
| Texture Sampler position |
VTextureSize.fr(image) | frame, shape, pixel |
| Returns the dimensions in pixels of the provided ScinImageBuffer. Roughly analogous to BufFrames. |
The ScinTween class describes a series of simple curves which the server can populate into a table, and then sample with interpolation with VGens at runtime. Scintillator provides VTweenGen VGens for sampling the tween curves over time, and VTweenSampler VGens for time-invariant tween sampling.
VGen | Rates | Dimensions | Description |
VTweenGen1.fr(tween, levelScale, levelBias, timeScale, timeBias) | frame, shape, pixel |
input | output | tween, 1, 1, 1, 1 | 1 |
| Samples a 1-dimensional tween table over time. |
VTweenGen2.fr(tween, levelScale, levelBias, timeScale, timeBias) | frame, shape, pixel |
input | output | tween, 1, 1, 1, 1 | 2 |
| Samples a 2-dimensional tween table over time. |
VTweenGen4.fr(tween, levelScale, levelBias, timeScale, timeBias) | frame, shape, pixel |
input | output | tween, 1, 1, 1, 1 | 4 |
| Samples a 4-dimensional tween table over time. |
VTweenSampler1.fr(tween, t) | frame, shape, pixel |
| Samples a 1-dimensional tween table at any point. |
VTweenSampler2.fr(tween, t) | frame, shape, pixel |
| Samples a 2-dimensional tween table at any point. |
VTweenSampler4.fr(tween, t) | frame, shape, pixel |
| Samples a 4-dimensional tween table at any point. |
Scintillator offers a few different means to determine the position of the current fragment shader relative to the geometry being rendered, or the onscreen pixel dimensions. The VTexPos VGen is in the Image Sampling section.
VGen | Rates | Dimensions | Description |
VNormPos.pr() | shape, pixel |
| Normalized fragment position |
VTexPos.pr() | shape, pixel |
| Texture Sampler position |
VFragCoord.pr() | pixel |
| Onscreen coordinates of current fragment in pixels |
These utility VGens allow the grouping of one-dimensional elements into vectors, access to individual elements within vectors, and lastly a convenience function to repeat (or splat) a single element across all elements within a vector.
Some VGens require inputs that are higher-dimensional vectors. To construct those inputs from single-dimensional components, Scintillator provides the VecN
classes.
VGen | Rates | Dimensions | Description |
VVec2.fr(x, y) | frame, shape, pixel |
| Construct a 2D vector from individual elements x and y |
VVec3.fr(x, y, z) | frame, shape, pixel |
| Construct a 3D vector from individual elements x and y |
VVec4.fr(x, y, z, w) | frame, shape, pixel |
| Construct a 4D vector from individual elements x and y |
VSplat2.fr(x) | frame, shape, pixel |
| Construct a 2D vector from a single element copied into both |
VSplat3.fr(x) | frame, shape, pixel |
| Construct a 3D vector from a single element copied into both |
VSplat4.fr(x) | frame, shape, pixel |
| Construct a 4D vector from a single element copied into both |
To break out a single-dimensional signal from a higher-dimensional vector, use the VX
and related classes. These follow the computer graphics naming conventions for elements within the vector, where the names x, y, z, w are used to indicate the first through fourth element respectively.
VGen | Rates | Dimensions | Description |
VX.fr(v) | frame, shape, pixel |
| Return the first element in the vector. |
VY.fr(v) | frame, shape, pixel |
| Return the second element in the vector. |
VZ.fr(v) | frame, shape, pixel |
| Return the third element in the vector. |
VW.fr(v) | frame, shape, pixel |
| Return the fourth element in the vector. |
Note that any vec4 output is considered valid ScinthDef output, but these can help with code clarity or with grouping of single-channel inputs into a vec4, sometimes with that fourth alpha component hard-coded to 1.0. In the future the server may perform opacity calling, so knowing an output is entirely opaque will allow VRGBOut and VBWOut to take advantage of that culling automatically.
VGen | Rates | Dimensions | Description |
VRGBOut.pr(red, green, blue) | pixel |
| Convenience object for color output at full opacity |
VRGBAOut.pr(red, green, blue, alpha) | pixel |
| Convenience object for color output with alpha channel |
VBWOut.pr(value) | pixel |
| Convenience object for black and white output at full opacity |
Scintillator offers per-element (or piecewise) operations as well as some more traditional vector mathematical operations such as dot and cross products. Many unary and binary operations are offerred with the same names as their analog counterparts,
VGen | Rates | Dimensions | Description |
VClamp.pr(v, min, max) | frame, shape, pixel |
input | output | 1, 1, 1 | 1 | 2, 2, 2 | 2 | 3, 3, 3 | 3 | 4, 4, 4 | 4 |
| Video equivalent of Clip UGen, piecewise bounds input v between [min, max] |
VLength.pr(v) | frame, shape, pixel |
| Returns the length of the vector x , or the square root of the sum of the squares |
VDistance.pr(u, v) | frame, shape, pixel |
| Computes the distance between u and v , which is the length of the vector v - u |
VStep.pr(step, x) | frame, shape, pixel |
input | output | 1, 1 | 1 | 2, 2 | 2 | 3, 3 | 3 | 4, 4 | 4 |
| Just like the binary operator thresh , returns 0 when x < step , otherwise x |
VMix.pr(v, u, a) | frame, shape, pixel |
input | output | 1, 1, 1 | 1 | 2, 2, 1 | 2 | 2, 2, 2 | 2 | 3, 3, 1 | 3 | 3, 3, 3 | 3 | 4, 4, 1 | 4 | 4, 4, 4 | 4 |
| Similar to the binary operator blend , returns a linear mix of v, u with a between [0, 1] . Supports piecewise blend or a single blend argument to apply to all components |
VDot.pr(u, v) | frame, shape, pixel |
input | output | 1, 1 | 1 | 2, 2 | 1 | 3, 3 | 1 | 4, 4 | 1 |
| Returns the dot product between u and v , or the sum of the product of each component in the vector |
VCross.pr(u, v) | frame, shape, pixel |
| Returns the cross product of u and v |
VNorm.pr(v) | frame, shape, pixel |
input | output | 1, 1 | 1 | 2, 2 | 2 | 3, 3 | 3 | 4, 4 | 4 |
| Returns a normalized vector parallel to v with length 1 |
The SuperCollider UGens support a broad variety of unary, binary, and n-ary mathematical operations. These are typically expressed as operators within the SynthDef flow, and are transformed by the SynthDef programming into one of the subclasss of BasicOpUGen before being sent to the server. Scintillator implements parallel classes for unary and binary operations, with the BasicOpVGen as the base class and UnaryOpVGen and BinaryOpVGen derived classes handling a subset of the operators handled by the UGen programming.
For documentation of these operators in base SuperCollider see the Operators overview or the SimpleNumber class documentation.
The following tables detail the current supported operations along with the ones that are not yet supported, the name of the VGen sent to the server to realize the operation, a brief explanation of their function and conceptual mathematical code. Since all numbers within a Scintillator ScinthDef must be floating-point, several of the integer operations like bit manipulation are marked as not applicable. If support is planned, but not yet implemented, the function is marked as not yet implemented.
For higher-dimensional signals all operations happen piecewise, meaning the operator is applied to each component of the signal independently. For example if b = a.neg
and both a
and b
are VVec4 objects then:
NOTE: All unary operations are supported at all rates, support inputs in 1-4 dimensions, and produce outputs of the same dimension.
Operator | VGen | Description | conceptual sclang code |
neg | VNeg | Unary negation | x = -1 * x |
reciprocal | VReciprocal | Reciprocal division | x = 1 / x |
bitNot | not applicable | Bitwise inversion | n/a |
abs | VAbs | Absolute value | if (x < 0, { x.neg }, { x }) |
asFloat | not applicable | Convert to float | n/a |
asInteger | not applicable | Convert to integer | n/a |
ceil | VCeil | Nearest integer greater than x | if ((x - x.asInteger) > 0, { (x.asInteger) + 1.0 }, { x }) |
floor | VFloor | Nearest integer lesser than x | x.asInteger.asFloat |
frac | VFract | Fractional remainder of x | x - x.asInteger |
sign | VSign | Sign, either -1, 0, or +1 matching sign of x | case { x < 0 } { -1.0 } { x == 0 } { 0.0 } { 1.0 } |
squared | converted to x * x | Square of a number | x * x |
cubed | converted to x * x * x | Cube of a number | x * x * x |
sqrt | VSqrt | Square root | x.sqrt |
exp | VExp | Natural exponentiation | e ** x |
midicps | not yet implemented | MIDI note to cycles per second | n/a |
cpsmidi | not yet implemented | Cycles per second to MIDI note | n/a |
midiratio | not yet implemented | Convert an interval in MIDI notes to a frequency ratio | n/a |
ratiomidi | not yet implemented | Convert a frequency ratio to an interval in MIDI notes | n/a |
ampdb | not yet implemented | Convert decibels to linear amplitude | n/a |
dbamp | not yet implemented | Convert linear amplitude to decibels | n/a |
octcps | not yet implemented | Convert decimal octaves to cycles per second | n/a |
cpsoct | not yet implemented | Convert cycles per second to decimal octaves | n/a |
log | VLog | Natural logarithm | x.log |
log2 | VLog2 | Base 2 logarithm | x.log2 |
log10 | not yet implemented | Base 10 logarithm | n/a |
sin | VSin | Sine | x.sin |
cos | VCos | Cosine | x.cos |
tan | VTan | Tangent | x.tan |
asin | VASin | Arcsine | x.asin |
acos | VACos | Arccosine | x.acos |
atan | VATan | Arctangent | x.atan |
rand | not yet implemented | Returns an evenly distributed random value between zero and x | x.rand |
rand2 | not yet implemented | Returns an evenly distributed random value beteen -x and +x | x.rand2 |
linrand | not yet implemented | Returns a linearly distributed random value between x and zero | x.linrand |
bilinrand | not yet implemented | Returns a linearly distributed random value between -x and +x | x.bilinrand |
sum3rand | not yet implemented | Returns a value from an approximation of a Gaussian random distribution between x and zero | x.sum3rand |
distort | not yet implemented | Nonlinear distortion of x | n/a |
softclip | not yet implemented | Distortion with a linear region from 0.25 to 0.75 | n/a |
coin | not yet implemented | Returns one or zero with the probability given by the argument | x.coin |
even | not applicable | True if dividable by two with no remainder | n/a |
odd | not applicable | True if dividable by two with a remainder of 1 | n/a |
rectWindow | not yet implemented | A value for a rectangular window function between 0 and 1 | n/a |
hanWindow | not yet implemented | A value for a Hanning window function between 0 and 1 | n/a |
welWindow | not yet implemented | A value for a Welsh window function between 0 and 1 | n/a |
triWindow | not yet implemented | A value for a triangle window function between 0 and 1 | n/a |
scurve | not yet implemented | Map x on to an S-curve | n/a |
ramp | not yet implemented | Map receiver onto a ramp starting at 0 | n/a |
isPositive | not applicable | True if x is >= 0 | n/a |
isNegative | not applicable | True if x is < 0 | n/a |
isStrictlyPositive | not applicable | True if x is > 0 | n/a |
rho | not yet implemented | The polar radius of x | n/a |
theta | not yet implemented | The polar angle of x | n/a |
ref | unknown | To be researched what this operator does | ?? |
Binary operations also happen piecewise, meaning that the binary operator is applied to each individual component separately. Conceptually if c = a * b
and both a
and b
are VVec4s then:
Operator | VGen | Description | conceptual sclang code |
rotate | unknown | To be researched what this operator does | ?? |
dist | unknown | To be researched what this opreator does | ?? |
+ | VAdd | Addition | a + b |
- | VSub | Subtraction | a - b |
* | VMul | Multiplication | a * b |
/ | VDiv | Division | a / b |
div | VDiv | Division, TODO: validate if this is really division | a / b |
mod | VMod | Floating-point modulo | a % b |
pow | VPow | Exponentiation | a ** b |
min | VMin | Piecewise minimum | if (a < b, { a }, { b }); |
max | VMax | Piecewise maximum | if (a > b, { a }, { b }); |
< | not applicable | True if a < b | n/a |
<= | not applicable | True if a <= b | n/a |
> | not applicable | True if a > b | n/a |
>= | not applicable | True if a >= b | n/a |
bitAnd | not applicable | Bitwise logical AND | n/a |
bitOr | not applicable | Bitwise logical OR | n/a |
bitXor | not applicable | Bitwise logical XOR | n/a |
hammingDistance | not applicable | Count of bits that are different | n/a |
lcm | not yet implemented | Least common multiple | n/a |
gcd | not yet implemented | Greates common divisor | n/a |
round | not yet implemented | Round to a multiple of a number | n/a |
roundUp | not yet implemented | Round up to a multiple of a number | n/a |
trunc | not yet implemented | Truncate to a muliple of a number | n/a |
atan2 | VATan2 | Arctangent of a / b | (a / b).atan |
hypot | not yet implemented | Square root of the sum of the squares | n/a |
hypotApx | unknown | To be researched what this operator does | ?? |
leftShift | not applicable | Shift bits to the left | n/a |
rightShift | not applicable | Shift bits to the right | n/a |
unsignedRightShift | not applicable | Shift bits to the right without preserving sign bit | n/a |
ring1 | not yet implemented | Ring modulation plus first source | (a * b) + a |
ring2 | not yet implemented | Ring modulation plus both sources | (a * b) + a + b |
ring3 | not yet implemented | Ring modulation variant | a * a * b |
ring4 | not yet implemented | Ring modulation variant | (a * a * b) - (a * b * b) |
difsqr | not yet implemented | Difference of squares | (a * a) - (b * b) |
sumsqr | not yet implemented | Sum of the squares | (a**2) + (b**2) |
sqrsum | not yet implemented | Square of the sum | (a + b)**2 |
absdif | not yet implemented | Absolute value of the difference | (a - b).abs |
thresh | not yet implemented | Thresholding | if (a < b, { 0 }, { a }); |
amclip | not yet implemented | Two quadrant multiply | if (b <= 0, { 0 }, { a * b }); |
scaleneg | not yet implemented | Scale negative part of input | if (a < 0, { a * b }, { a }); |
clip2 | not yet implemented | Clip a to +/-b | if (a.abs < b, { b * a.sign }, { a }); |
fold2 | not yet implemented | Bilateral folding | n/a |
wrap2 | not yet implemented | Bilateral wrapping | n/a |
excesss | not yet implemented | Residual clipping | n/a |
firstArg | unknown | To be researched what this operator does | ?? |
rrand | not yet implemented | Generate a uniformly distributed pseudorandom number in [a, b] | n/a |
exprand | not yet implemented | Generate an exponentially distributed pseudorandom number in [a, b] | n/a |
@ | unknown | To be researched what this operator does | ?? |
|| | not applicable | Boolean logical OR | n/a |
&& | not applicable | Boolean logical AND | n/a |
xor | not applicable | Boolean logical XOR | n/a |
nand | not applicable | Boolean logical NAND | n/a |