<!--
Copyright Disney Enterprises, Inc.  All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License
and the following modification to it: Section 6 Trademarks.
deleted and replaced with:

. Trademarks. This License does not grant permission to use the
trade names, trademarks, service marks, or product names of the
Licensor and its affiliates, except as required for reproducing
the content of the NOTICE file.

You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
-->

<h3>Shader/XGen/Paint3d Expressions</h3>
<ul>
  <li><a href="#Variables">Variables</a></li>
  <li><a href="#Color_Masking_and_Remapping_Functions">Color, Masking,
and Remapping Functions</a></li>
  <li><a href="#Noise_Functions">Noise Functions</a></li>
  <li><a href="#Texture_Lookup_Functions">Texture Lookup Functions</a></li>
  <li><a href="#Selection_Functions">Selection Functions</a><br>
  </li>
  <li><a href="#General_Math_Functions">General Math Functions and Constants</a></li>
  <li><a href="#Trigonometry_Functions">Trigonometry Functions</a></li>
  <li><a href="#Vector_Functions">Vector Functions</a></li>
  <li><a href="#Vector_Support">Vector Support</a></li>
  <li><a href="#Curve_Functions">Curve Functions</a></li>
  <li><a href="#Misc_Functions">Misc Functions</a></li>
  <li><a href="#Operators">Operators</a></li>
  <li><a href="#Assignment_Operators">Assignment Operators</a></li>
  <li><a href="#Comments">Comments</a></li>
  <li><a href="#Custom_Plugins">Custom Plugins</a></li>
</ul>
<h4><a name="Variables"></a>Variables<br>
</h4>

<p>
The specific variables that are used depends on the context that the expression
language is being used in. A common convention we use is to use the following
variables in different contexts. These are just examples. Usually the developer
of the software using expressions will register the acceptable variables with
autocomplete help so that when you type $ in the expression editor a list of
acceptable variables popup.
</p>


Image Variables
<ul>
  <li><b>$u</b>, <b>$v </b>-texture coords (scalars)</li>
  <li><b>$Cs</b>, Source image color (vector)
  <li><b>$As</b>, Source image alpha (scalar)
</ul>

Surface Shading or Texturing Activities
<ul>
  <li><b>$Cs</b>, Source image color (vector)
  <li><b>$u</b>, <b>$v </b>-texture coords (scalars)</li>
  <li><b>$P </b>- surface point (vector). Note: $P is sampled from the Pref geometry (if available)</li>
  <li><b>$N</b> - surface normal</li>
  <li><b>$objectId</b> - per-surface unique object Id, typically a small integer</li>
  <li><b>$frame</b> - current frame number</li>
</ul>

<b>Local Variables<br>
</b><br>
Local variables can be defined at the start of the expression:<br>
<div style="margin-left: 40px;"><br>
$a = noise($P);<br>
$b = noise($a * 1);<br>
pow($a, 0.5) + $b<br>
<br>
</div>
External variables can also be overridden by local assignment.&nbsp;
This can be useful to scale the noise frequency for instance:<br>
<div style="margin-left: 40px;"><br>
$P = $P * 10; # increase noise frequency<br>
fbm(vnoise($P) + $P/4)<br>
</div>
<br>
<h4><a name="Color_Masking_and_Remapping_Functions"></a>Color,
Masking,and Remapping Functions</h4>
float <b>clamp</b> ( float x, float
lo, float hi )&nbsp; - constrain x to range [lo, hi]<br>
<br>
float <b>compress</b> ( float x,
float lo, float hi )&nbsp;
<div style="margin-left: 40px;">Compress the dynamic range from [0..1]
to [lo..hi]<br>
</div>
float <b>expand</b> ( float x, float
lo, float hi )
<div style="margin-left: 40px;">Expand the dynamic range from [lo..hi]
to [0..1]<br>
</div>
float <b>contrast</b> ( float x,
float c ) <br>
<div style="margin-left: 40px;">Adjust the contrast.&nbsp; For c from
0 to 0.5, the contrast is decreased.&nbsp; For c &gt; 0.5, the contrast
is increased. NOTE: internally contrast will clamp to [0,1] range.<br>
</div>
float <b>invert</b> ( float x ) -
Invert the value.&nbsp; Defined as 1-x.<br>
<br>
float <b>remap</b> ( float x, float
source, float range, float falloff, int interp )<br>
<div style="margin-left: 40px;">General remapping function.&nbsp; When
x is
within +/- <i>range</i> of source, the result is one.&nbsp; The
result falls to zero beyond that range over <i>falloff</i>
distance.&nbsp; The
falloff shape is controlled by <i>interp</i>. Numeric values or named
constants may be used:<br>
&nbsp;&nbsp;&nbsp;&nbsp;int <b>linear</b>
= 0<br>
&nbsp;&nbsp;&nbsp;&nbsp;int <b>smooth</b> = 1<br>
&nbsp;&nbsp;&nbsp;&nbsp;int <b>gaussian</b> = 2<br>
</div>
<br>
color <b>saturate</b> ( color x, float amt ) <br>
<div style="margin-left: 40px;">Scales saturation of color by amt.
The color is scaled around the rec709 luminance vlue, and negative
results are clamped at zero.<br>
</div>
color <b>hsi</b> ( color x, float h, float s, float i, float map=1 ) <br>
<div style="margin-left: 40px;">The hsi function shifts the hue by h
(in degrees) and scales the saturation and intensity by s and i
respectively.&nbsp; An map may be supplied which will control the shift
- the full shift will happen when the map is one and no shift will
happen when the map is zero.&nbsp; The shift will be scaled back for
values between zero and one.<br>
</div>
color <b>midhsi</b> ( color x, float h, float s, float i, float map, float
falloff=1, int interp=0 ) <br>
<div style="margin-left: 40px;">The midhsi function is just like the
hsi function except that the control map is centered around the mid
point (value of 0.5) and can scale the shift in both directions.&nbsp;
At the mid
point, no shift happens.&nbsp; At 1.0, the full shift
happens, and at 0.0, the full inverse shift happens.&nbsp; Additional
falloff and interp controls are provided to adjust the map using the
remap function.&nbsp; The default falloff and interp values result in
no remapping. <br>
</div>
<br>
color <b>rgbtohsl</b> ( color rgb )<br>
color <b>hsltorgb</b> ( color hsl )<br>
<div style="margin-left: 40px;">RGB to HSL color space
conversion.&nbsp; <br>
HSL is Hue, Saturation, Lightness (all in range [0..1] )<br>
These functions have also been extended to support rgb and hsl values
outside of the range [0..1] in a reasonable way.&nbsp; For any rgb or
hsl value (except for negative s values), the conversion is
well-defined and reversible.<br>
</div>
<br>
float <b>bias</b> ( float x, float b)
<div style="margin-left: 40px;">Variation of gamma where control
parameter goes from 0 to 1 with values &gt; 0.5 pulling the curve up
and values &lt; 0.5 pulling the curve down.&nbsp; Defined as pow(x,
log(b)/log(0.5)).<br>
</div>
float <b>gamma</b> ( float x, float g) - pow(x, 1/g)<br>
<br>
float <b>fit</b> ( float x, float a1, float b1, float a2, float b2 )
<div style="margin-left: 40px;">Linear remapping of [a1..x..b1] to
[a2..x..b2]<br>
</div>
float <b>mix</b> ( float a, float b,
float alpha )
<div style="margin-left: 40px;">Blend of a and b according to
alpha.&nbsp; Defined as
a*(1-alpha) + b*alpha.<br>
</div>
<br>
float <b>boxstep</b> ( float x, float a )<br>
float <b>gaussstep</b> ( float x, float a, float b ) <br>
float <b>linearstep</b> (
float x, float a, float b ) <br>
float <b>smoothstep</b> ( float x, float a, float b ) <br>
<div style="margin-left: 40px;">The step functions are zero for x &lt;
a and one for x &gt; b (or x &gt; a in the case of boxstep).&nbsp;
Between a and b, the value changes continuously between zero and
one.&nbsp; The gausstep function uses the standard gaussian "bell"
curve which is based on an exponential curve.&nbsp; The smoothstep
function uses a cubic curve.&nbsp; Intuitively, gausstep is has a
sharper transition near one and a softer transition near zero whereas
smoothstep is
has a medium softness near both one and zero.<br>
</div>
<br>
<h4><a name="Noise_Functions"></a>
Noise Functions</h4>
float <b>rand</b> ( [float min, float max], [float seed] )<br>
<div style="margin-left: 40px;">Random number between min..max (or 0..1
if unspecified).<br>
If a seed is supplied, it will be used in addition to the internal
seeds and may be used to create multiple distinct generators.<br>
</div>
float <b>hash</b> ( float seed1, [float seed2, ...] )<br>
<div style="margin-left: 40px;">Like rand, but with no internal
seeds.&nbsp; Any number of seeds may be given and the result will be a
random function based on all the seeds.<br>
</div>
float <b>cellnoise</b> ( vector v )
float <b>cellnoise1</b> ( float x ) <br>
float <b>cellnoise2</b> ( float x,
float y ) <br>
float <b>cellnoise3</b> ( float x,
float y, float z ) <br>
color <b>ccellnoise</b> ( vector v )
- color cellnoise<br>
<div style="margin-left: 40px;">cellnoise generates a field of constant
colored cubes based on the integer location.&nbsp; This
is the same as the prman cellnoise function.<br>
</div>
<br>
float <b>noise</b> ( vector v ) <br>
float <b>noise</b> ( float x, float y ) <br>
float <b>noise</b> ( float x, float y, float z ) <br>
float <b>noise</b> ( float x, float y, float z, float w ) <br>
color <b>cnoise</b> ( vector v) - color noise<br>
float <b>snoise</b> ( vector v) - signed noise w/ range -1 to 1.<br>
vector <b>vnoise</b> (vector v ) - signed vector noise<br>
color <b>cnoise4</b> ( vector v, float t) - color noise<br>
float <b>snoise4</b> ( vector v, float t) - signed noise w/ range -1 to 1.<br>
vector <b>vnoise4</b> (vector v, float t ) - signed vector noise<br>
float <b>pnoise</b> ( vector v, vector period ) - periodic noise<br>
<div style="margin-left: 40px;">noise is a random function that
smoothly blends between samples at integer locations.&nbsp; This is Ken
Perlin's original noise function.<br>
</div>
<br>
float <b>perlin</b> ( vector v ) <br>
color <b>cperlin</b> ( vector v) - color noise<br>
float <b>sperlin</b> ( vector v) - signed noise w/ range -1 to 1.<br>
vector <b>vperlin</b> (vector v ) - signed vector noise<br>
<div style="margin-left: 40px;">"Improved Perlin Noise", based on Ken
Perlin's 2002 Java reference code.<br>
</div>
<br>
float <b>fbm</b> ( vector v, int
octaves&nbsp;=&nbsp;6, float lacunarity&nbsp;=&nbsp;2, float
gain&nbsp;=&nbsp;0.5 )<br>
color <b>cfbm</b> ( vector v, int
octaves&nbsp;=&nbsp;6, float lacunarity&nbsp;=&nbsp;2, float
gain&nbsp;=&nbsp;0.5 )<br>
vector <b>vfbm</b> ( vector v, int
octaves&nbsp;=&nbsp;6, float lacunarity&nbsp;=&nbsp;2, float
gain&nbsp;=&nbsp;0.5 )<br>
float <b>fbm4</b> ( vector v, float time, int
octaves&nbsp;=&nbsp;6, float lacunarity&nbsp;=&nbsp;2, float
gain&nbsp;=&nbsp;0.5 )<br>
color <b>cfbm4</b> ( vector v, float time, int
octaves&nbsp;=&nbsp;6, float lacunarity&nbsp;=&nbsp;2, float
gain&nbsp;=&nbsp;0.5 )<br>
vector <b>vfbm4</b> ( vector v, float time, int
octaves&nbsp;=&nbsp;6, float lacunarity&nbsp;=&nbsp;2, float
gain&nbsp;=&nbsp;0.5 )<br>
<div style="margin-left: 40px;">fbm (Fractal Brownian Motion)
is a multi-frequency noise function.&nbsp; The base frequency is the
same as the
"noise" function.&nbsp; The total number of frequencies is controlled
by <i>octaves</i>.&nbsp; The <i>lacunarity</i> is the spacing between
the frequencies - a value of 2 means each octave is twice the previous
frequency.&nbsp; The <i>gain</i> controls how much each frequency is
scaled relative to the previous frequency.<br>
</div>
<br>
float <b>turbulence</b> ( vector v,
int octaves&nbsp;=&nbsp;6, float lacunarity&nbsp;=&nbsp;2, float
gain&nbsp;=&nbsp;0.5 )<br>
color <b>cturbulence</b> ( vector v,
int octaves&nbsp;=&nbsp;6, float lacunarity&nbsp;=&nbsp;2, float
gain&nbsp;=&nbsp;0.5 )<br>
vector <b>vturbulence</b> ( vector v,
int octaves&nbsp;=&nbsp;6, float lacunarity&nbsp;=&nbsp;2, float
gain&nbsp;=&nbsp;0.5 )<br>
<div style="margin-left: 40px;">turbulence is a variant of fbm
where
the absolute value of each noise term is taken.&nbsp; This gives a more
billowy appearance. <br>
</div>
<br>
<br>
float <b>voronoi</b> ( vector v, int type&nbsp;=&nbsp;1,
float jitter&nbsp;=&nbsp;0.5, float fbmScale&nbsp;=&nbsp;0, int
fbmOctaves&nbsp;=&nbsp;4,
float fbmLacunarity&nbsp;=&nbsp;2, float fbmGain&nbsp;=&nbsp;0.5)<br>
color <b>cvoronoi</b> ( vector v, int type&nbsp;=&nbsp;1,
float jitter&nbsp;=&nbsp;0.5, float fbmScale&nbsp;=&nbsp;0, int
fbmOctaves&nbsp;=&nbsp;4,
float fbmLacunarity&nbsp;=&nbsp;2, float fbmGain&nbsp;=&nbsp;0.5)<br>
vector <b>pvoronoi</b> ( vector v,
float jitter&nbsp;=&nbsp;0.5, float fbmScale&nbsp;=&nbsp;0, int
fbmOctaves&nbsp;=&nbsp;4,
float fbmLacunarity&nbsp;=&nbsp;2, float fbmGain&nbsp;=&nbsp;0.5)<br>
<div style="margin-left: 40px;">voronoi is a cellular noise
pattern.
It is a jittered variant of cellnoise. <b>cvoronoi</b> returns a random color for each cell and <b>pvoronoi</b> returns the point location of the center of the cell.  The type parameter describes different variants of the noise function.&nbsp;
The jitter param controls how
irregular
the pattern is (jitter = 0 is like ordinary cellnoise).&nbsp; The fbm*
params can be used to distort
the noise field.&nbsp; When fbmScale
is zero (the default), there is no distortion.&nbsp; The remaining
params are the same as for the fbm function.<br>
Voronoi types 1 through 5:<br>
<img src="Se_voronoi_1.png">&nbsp;
<img src="Se_voronoi_2.png">&nbsp;
<img src="Se_voronoi_3.png">&nbsp;
<img src="Se_voronoi_4.png">&nbsp;
<img src="Se_voronoi_5.png">&nbsp;
Note: There is no guarantee that values will be 0,1, so you may need to clamp if
using a function like gamma() or contrast() which expect [0,1] input.
</div>
<br>
<h4><a name="Texture_Lookup_Functions"></a>
Texture Lookup Functions</h4>
vector <b>map</b>( string filename, [float format-arg], [float u, float v], [int channel] )<br>
<div style="margin-left: 40px;">Access a texture map.<br>
<b>Note: strings must be enclosed in single or double quotes.</b><br>
</div>
<br>
vector <b>projmap</b> ( string
coordspace, string type, string
filename, [float format-arg] ) <br>
<div style="margin-left: 40px;">Projects a texture map from the given
named coordinace space using the specified projection type.<br>
</div>
<br>
<h4><a name="Selection_Functions"></a>Selection Functions</h4>
int <b>cycle</b>
( int index, int loRange, int hiRange )<br>
<div style="margin-left: 40px;">Cycles through values between loRange
and hiRange based on supplied index.&nbsp; This is an offset "mod"
function.&nbsp; The result is computed as (loRange + value %
(hiRange-loRange+1)).<br>
</div>
<br>
int <b>pick</b> ( float index, int loRange, int hiRange, [float
weights, ...] )<br> <div style="margin-left: 40px;">Picks values
randomly between loRange and hiRange based on supplied index (which is
automatically hashed).&nbsp; The values will be distributed according
to the supplied weights.&nbsp; Any weights not supplied are assumed to
be 1.0.<br>
<br>
</div>
float <b>choose</b> ( float index,
float choice1, float choice2, [...] )<br>
<div style="margin-left: 40px;">Chooses one of the supplied choices
based on the index (assumed to be in range [0..1]).<br>
<br>
</div>
float <b>wchoose</b> ( float index,
float choice1, float weight1, float choice2, float weight2, [...] )<br>
<div style="margin-left: 40px;">Chooses one of the supplied choices
based on the index (assumed to be in range[0..1]).
The values will be distributed according to the supplied weights.<br>
</div>
<br>
Examples:<br>
<ul>
  <li>pick ( value, 1, 10 ) - integer values between 1 and 10 will be
returned</li>
  <li>pick ( value, 1, 10, 2, 2.5 ) - the values 1 and 2 will be
returned twice and 2.5 times as often respectively as compared to the
other values (3-10)</li>
  <li>pick ( value, 10, 20, 1, 1, 0 ) - values 10, 11, and 13 through
20 will be returned (12 is skipped due to zero weight)</li>
</ul>
Note: the filename for the map and
projmap functions can specify an optional format-arg which will be
inserted into the filename as indicated in the examples below:<br>
<ul>
  <li>map( 'noise.%d.map.tx', 10 ) &nbsp; <i>references a file named
'noise.10.map.tx'</i><br>
  </li>
  <li>map( 'fenceColor-%04d.tx', 12 )&nbsp;&nbsp;&nbsp; <i>references
a file named
'fenceColor-0012.tx'</i></li>
  <li>map( 'map-%d.tx', $objectId)&nbsp;&nbsp; <i>builds the filename
based on the object Id</i></li>
  <li>map( 'map-%d.tx', cycle($objectId, 10, 20))&nbsp;&nbsp; <i>cycles
through maps 10 through 20 based on
object Id</i></li>
  <li>map( 'map-%d.tx', pick($objectId, 10, 20)) &nbsp; <i>picks maps
10 through 20 randomly based on
object Id</i><br>
  </li>
</ul>
<br>
<h4><a name="General_Math_Functions"></a>
General Math Functions and Constants<br>
</h4>
float <b>PI</b>= 3.14159...<br>
float <b>E </b>= 2.71828...<br>
float <b>abs</b> ( float x) - absolute value of x<br>
float <b>max</b> ( float a, float b )
- greater of a and b<br>
float <b>min</b> ( float a, float b )
- lesser of a and b<br>
float <b>fmod</b> ( float x, float y)
- remainder of x / y (also available as '<b>%</b>' operator)<br>
<br>
float <b>cbrt</b> ( float x ) - cube root<br>
float <b>sqrt</b> ( float x ) - square root<br>
<br>
float <b>ceil</b> ( float x ) - next higher integer<br>
float <b>floor</b> ( float x ) - next lower integer<br>
float <b>round</b> ( float x ) - nearest integer<br>
float <b>trunc</b> ( float x ) - nearest integer towards zero<br>
<br>
float <b>exp</b> ( float x ) - E raised to the x power<br>
float <b>log</b> ( float x ) - natural logarithm<br>
float <b>log10</b> ( float x ) - base 10 logarithm<br>
float <b>pow</b> ( float x, float y )
- x to the y power (also available as '<b>^</b>'
operator)<br>
<br>
<h4><a name="Trigonometry_Functions"></a>
Trigonometry Functions</h4>
float <b>acos</b> ( float x ) - arc cosine<br>
float <b>asin</b> ( float x ) - arc sine<br>
float <b>atan</b> ( float x ) - arc tangent<br>
float <b>atan2</b> ( float y, float x)
- arc tangent of y/x between -PI and PI<br>
<br>
float <b>cos</b> ( float x ) - cosine<br>
float <b>sin</b> ( float x ) - sine<br>
float <b>tan</b> ( float x ) - tangent<br>
<br>
float <b>acosd</b> ( float x ) - arc cosine in degrees<br>
float <b>asind</b> ( float x ) - arc sine in degrees<br>
float <b>atand</b> ( float x ) - arc tangent in degrees<br>
float <b>atan2d</b> ( float y, float x )
- arc tangent in degrees of y/x between -180 and 180<br>
<br>
float <b>cosd</b> ( float x ) - cosine in degrees<br>
float <b>sind</b> ( float x ) - sine in degrees<br>
float <b>tand</b> ( float x ) - tangent in degrees<br>
<br>
float <b>acosh</b> ( float x ) - hyperbolic arc cosine<br>
float <b>asinh</b> ( float x ) - hyperbolic arc sine<br>
float <b>atanh</b> ( float x ) - hyperbolic arc tangent<br>
<br>
float <b>cosh</b> ( float x ) - hyperbolic cosine<br>
float <b>sinh</b> ( float x ) - hyperbolic sine<br>
float <b>tanh</b> ( float x ) - hyperbolic tangent<br>
<br>
float <b>deg</b> ( float x ) - radians to degrees<br>
float <b>rad</b> ( float x ) - degrees to radians<br>
<br>
float <b>hypot</b> ( float x, float y
) - length of 2d vector (x,y)<br>
<br>
<h4><a name="Vector_Functions"></a>
Vector Functions</h4>
float <b>angle</b>( vector a, vector b )
- angle between two vectors (in radians)<br>
vector <b>cross</b> ( vector a, vector b ) - vector cross product<br>
float <b>dist</b> ( vector a, vector b ) - distance between two points<br>
float <b>dot</b> ( vector a, vector b) - vector dot product<br>
float <b>length</b> ( vector v ) - length of vector<br>
vector <b>norm</b> ( vector v ) - vector scaled to unit length<br>
vector <b>ortho</b> ( vector a, vector b ) 
- vector orthographic to two vectors<br>
vector <b>up</b> ( vector v, vector up ) 
- rotates v such that the Y axis points in the given up direction<br>
vector <b>rotate</b> ( vector v, vector axis, float angle ) - rotates v around axis by given angle (in radians)<br>
<br>
<h4><a name="Vector_Support"></a>Vector Support</h4>
Vectors (points, colors, or 3d vectors) may be intermixed with
scalars (simple float values).&nbsp; If a scalar is used in a vector
context, it is
replicated into the three components (e.g. 0.5 becomes [0.5, 0.5, 0.5]
).&nbsp; If a vector is used in a scalar context, only the first
component is used.<br>
<br>
One of the benefits of this is that all the functions that are defined
to work with scalars automatically extend to vectors.&nbsp; For
instance, <b>pick,</b> <b>choose,</b> <b>cycle,</b> <b>spline,</b> etc., will work just fine with vectors.<br>
<br>
Arithmetic operators such as +, *, etc., and scalar functions are
applied component-wise to vectors.&nbsp; For example, applying the
gamma
function to a map adjusts the gamma of all three color channels.<br>
<br>
<h4><a name="Curve_Functions"></a>Curve Functions</h4>
<p>Interpolation of parameter values to a set of control points is governed by the
following functions.
</p><p>
color <b>curve</b>(float param,float pos0,color val0,int interp0,float pos1,color val1,int interp1,[...])<br>
Interpolates color ramp given by control points at 'param'. Control points are specified
by triples of parameters pos_i, val_i, and interp_i. Interpolation codes are
0 - none, 1 - linear, 2 - smooth, 3 - spline, 4 - monotone (non-oscillating) spline
</p><p>
float <b>curve</b>(float param,float pos0,float val0,int interp0,float pos1,float val1,int interp1,[...])<br>
Interpolates a 1D ramp defined by control points at 'param'. Control points are specified
by triples of parameters pos_i, val_i, and interp_i. Interpolation codes are
0 - none, 1 - linear, 2 - smooth, 3 - spline, 4 - monotone (non-oscillating) spline
</p><p>
float <b>spline</b>(float param,float y1,float y2,float y3,float y4,[...])<br>
Interpolates a set of values to the parameter specified where y1, ..., yn are
distributed evenly from [0...1]
</p>
<h4><a name="Misc_Functions"></a>Misc Functions</h4>
<p>
void <b>printf</b>(string format,[param0,param1,...])<br>
Prints a string to stdout that is formatted as given. Formatting parameters
possible are %f for float (takes first component of vector argument) or %v for
vector.  For example if you wrote printf("test %f %v",[1,2,3],[4,5,6]); you
would get "test 1 [4,5,6]".
</p>

<h4><a name="Operators"></a>Operators (listed in decreasing precedence)</h4>
<table cellpadding="2" cellspacing="2" border="0">
  <tbody>
    <tr>
      <td><b>[</b>&nbsp;a,&nbsp;b,&nbsp;c&nbsp;<b>]</b><br>
      <b>[&nbsp;</b> n&nbsp; <b>]</b> </td>
      <td>vector constructor<br>
vector component access - n must be 0, 1, or 2&nbsp; (e.g. $P[0]) </td>
    </tr>
    <tr>
      <td><b>^</b></td>
      <td>exponentiation (same as pow function) </td>
    </tr>
    <tr>
      <td><b>!</b></td>
      <td>logical NOT </td>
    </tr>
    <tr>
      <td><b>~</b></td>
      <td>inversion (i.e. ~$A gives the same result as 1-$A) </td>
    </tr>
    <tr>
      <td><b>*&nbsp;/&nbsp; %</b></td>
      <td>multiply, divide, modulus (same as fmod function) </td>
    </tr>
    <tr>
      <td><b>+&nbsp;-</b></td>
      <td>add, subtract </td>
    </tr>
    <tr>
      <td><b>&lt;&nbsp;&gt;&nbsp; &lt;=&nbsp; &gt;=</b></td>
      <td>comparison (only uses [0] component of vectors) </td>
    </tr>
    <tr>
      <td><b>==&nbsp; !=&nbsp; </b></td>
      <td>equality, inequality </td>
    </tr>
    <tr>
      <td><b>&amp;&amp;</b></td>
      <td>logical AND </td>
    </tr>
    <tr>
      <td><b>||</b></td>
      <td>logical OR </td>
    </tr>
    <tr>
      <td><b>?&nbsp;:</b></td>
      <td>conditional (like if-then-else, e.g.&nbsp; $u &lt; .5 ? 0 :
1) </td>
    </tr>
    <tr>
      <td><b>-&gt;</b></td>
      <td>apply - The function on the right of the arrow is applied to
the expression on the left.<br>
Examples:<br>
$Cs&nbsp;-&gt;&nbsp;contrast(.7)
-&gt;&nbsp;clamp(0.2,&nbsp;0.8)<br>
$u&nbsp;-&gt;&nbsp;hsi(20,&nbsp;1.2,&nbsp;1,&nbsp;$Cs&nbsp;-&gt;&nbsp;gamma(1.2))</td>
    </tr>
  </tbody>
</table>
<br>
<h4><a name="Assignment_Operators"></a>Assignment Operators</h4>
<p>
  Besides the basic assignment statement "$foo=$bar;" you can also do operator
  assignments such as "$foo+=$bar;" which is equivalent to
  "$foo=$foo+$bar;". Additionally there are, +=, -=, /=, %=, *=, ^=.
  
</p>

<h4><a name="Comments"></a>Comments</h4>
Any characters following a '#' to the
end of the line are ignored and may be used as a comment, or for
"commenting out" part of the expression.&nbsp; For a multi-line
expression, each line may have its own comment.<br>
<br>
<h4><a name="Custom_Plugins"></a>Custom Plugins</h4>
Custom fuctions may be written in C++ and loaded as one or more dynamic
plugins.&nbsp; See <a href="SeExpressionPlugins.html">Writing Custom
Expression Plugins</a> for more details.<br>
<br>
