Language Reference



Variables

ProXimus pseudo-script works by defining variables which are referenced by other variables or used to draw to the screen. in order to define a variable you need to start a new line with the '@' symbol it must immediately be followed by the name of the variable, and then immediately followed by the '=' symbol which must be followed by the expression the variable is equivalent to. for example to define a variable named new to be x*y you would type

@new= x*y

note that after the '=' the language is no longer concerned with white space, ware as variable names can accept characters which the expression system will not recognize (such as a space or tab) this can allow you to make variables which can not be used by anything other than the evaluator (assigned to a color channel), but it is quite posable that invalid characters will not be allowed in future development. also if the expression system finds a string which it does not recognize (anything which is not a built in function, a built in variable, or a defined variable or layer) it will assign that string a value of zero, currently there is no error message about this, but this will likely be fixed in future development. all variables are local and can not (at this time) be evaluated outside of there parent layer

a defined variable can be used in any later defined variable.
for example if you define one variable A and another variable B after you have defined A, B can use the value of A

@A=3
@B=2*A

in this case the evaluated value of B would be 2*3=6.
Note that the following example is not valid

@B=2*A
@A=3

in this instance the variable B tries to use the variable A, but A has not been defined yet, it will be given the value of 0 until it is defined, so B would evaluate to 2*0=0. keep in mind that you do not change the value of a variable after it is defined any more than you would declare a variable more than once in C++, in the context of this language it just doesn't make any sense.

Layers

Layers are the main method by which you will work with ProXimus to draw images. layers allow you to partition complex images into smaller subsections, letting you cache results and fetch them in another layer, it also lets you make approximations of expressions at a lower resolution and up sample them to a higher resolution (ProXimus uses bicubic interpolation to scale images up).
all layers have a few things in common, they all have a resolution for both the x and y directions, they all have a single color space mode, they all have variables which they need to have defined, and they can all be sampled by other layers in the same way within an expression.

Layer Sampling

to sample a layer in an expression for a variable in another layer (a layer sampling it's self is posable but the results are undefined, it usually won't crash though) you need to simply use the layer name, followed by the color component you want to use (currently colors are saved in an RGB form and converted to other color spaces when sampled, this may change in the future, this has important repercussions if , for example, you try to sample the 'h' component) you may select any color component for any color space, though there is limited support for anything other than RGB (HSL has some support, other color spaces have poorly tested support), following this you need the x/y coordinates (0 to 1, origin in the upper left) of the point in that layer you wish to sample separated by a coma within parentheses
for example if you wished to sample the red color component of a layer named 'alayer' at the same point as in your current layer, you would need something that looked like this:

alayer.r(x,y)

keep in mind that sense the local coordinates are in the range of 0 to 1 and the sampling coordinates are in the range 0 to 1 and the lower case x and y are zeroed at the upper left corner passing these variables will result in sampling the image point by point, if the two images are the same resolution it will pull results exactly, otherwise it will approximated bicubicly. do not limit yourself, this very simple sampling method is rarely useful, VERY nice effects can be made by having complex expressions sampling another layer, in particular, functions which use ang and r look good on radial images.

Global Layers

the main type of layer you will be dealing with in ProXimus is the global layer. every workspace needs to have at least one global layer in order to be useful (though by default no layers are created because there is no good choice for default resolution or color space). having more than one layer in a workspace can allow you to make multiple images at the same time, though this is not recommended unless the images will be either using a common source layer or will be used as sources by a single layer later. all global layers can be evaluated on there own, and have images saved. all global layers can be sampled by any other layer at any point in time after there creation. all have the majority of there details managed by the program, the only aspect exposed for direct manipulation is variable definition, resolution, color space color channel assignments are all modified using the program rather than editing script directly.

Local Layers

local layers are used in situations were you will be using a cheap to evaluate layer as a source only for one layer, no other layer should have access to it, and the existence of this local layer is essential to it's parent. the most common use for local layers is as a noise layer which will be sampled to make more complex noise. local layers cannot be evaluated on there own, they will be re-evaluated every time there parent is, before there parent's variables are evaluated, and in the order in which they appear in the script. in a local layer all aspects of the layer are defined within the script of the parent.

Defining Local Layers

Local layers are defined by placing the name of the new variable directly after the '$' symbol, the resolution of the local layer is given with the two dimensions separated by a coma and within square brackets, following the dimensions the color space if given within angle brackets (currently the supported color space options are RGB, HSL, HPV, CMYK, YUV, and BW). following color space should be the layer's variable definition within curly brackets, the variable definition for a local layer works exactly like a global layer's. finally after variable definition you need color channel assignment, within angle brackets you need to enter the name of the variable you want to use for the component, there needs to be as many variables as the color space has channels (CMYK has 4 channels, BW has 1, all others currently have 3) with a '|' separating them.
here is an example local layer that is filled with random noise (the rand function will return a value between 0 and the number passed)

$N[512,512]<RGB>{
@A=rand(1)
@B=rand(1)
@C=rand(1)
}<A|B|C>

this layer can be sampled within it's parent as if it were any other layer.(i.e. @R=N.r(x,y))

Image Layers

Image layers are a recent addition to ProXimus, and will likely undergo many changes in the future but there current behavior will be documented here.
After forming an image layer the default script will have two portions, the first, most important, and most unusual look like this

++img=""

what you need to do here is enter the path to an image file, this can be either a full path or a local path (you can set the texture path for local paths using the "set texture path" option in the options menu).

The second part will be variable used to look up image data, the default script will have it look up data on a one to one basis and will be used in most situations, but you could make other lookup methods if you wanted too.

Summations

Summations are a very unusual feature, that has a lot of posabilities. with a summation you can make many types of algorithms, not simply those which are traditionally considered summations ProXimus summations are actually more like a while loop which will return the first variable defined within it. summations are composed of a test and a set of there own variables (like a local layer). but these variables are defined quite a bit differently than any normal variable and they behave much differently than most, for one thing they actually hold a value that can be changed, for another thing they can be used before they are defined. but like variables of a layer, summation variables can not be accessed outside there scope. a summation is defined within expression, it is classified as an operand which means it returns a value, the return value is the value of the first defined variable after the test fails.
To make a summation, you need to use the key word 'sum' imediately following this should be in parenthesis the test definition followed by one or more variable definitions. the test is actually a special variable you never have access to, but so long as the test does not evaluate to zero the summation will continue to evaluate iterations. the test is defined simply with the key word 'test' followed immediately within parenthesis by an expression which should use one or more of the summation's local variables (if you don't you will likely cause an infinite loop which there currently is no way to break out of, save your work a lot when working with summations). to define the local variables you need to use the key word 'var' followed immediately within parenthesis separated by comas, the name of the variable, an expression describeing it's initial value (if you reference the loacl variable it's self at this point it should be equal to 0), and an expression describeing what it's value should be set to for each itteration. local variables are evaluated in the order you define them.
here is a sample summation which I use for generating a type of perlin noise

@R=sum(test(i<513),var(l,0,l+N.r(x/i+x/(2*i),y/i+y/(2*i))/(512/i)),var(i,1,i*2))

note the test, which says that the sum will continue evaluating all variables so long as after the end of one evaluation iteration i < 513
following the test is a variable definition for the local variable l, it's initial value will be 0, and every iteration it's value will be set to a sampling of the layer N's red color component at a point in an ever shrinking subsection of N. finally we have the variable definition for the variable i, which has an initial value of 1, and will be set to twice it's value. due to the order l will use i's initial value of 1, if the definition order had been reversed l's first evaluation would have evaluated i as 2 instead (in addition the summation would have returned 1024 every time no mater what, because i would have been the first defined variable).



back to the ProxDox home