The material controller scripting language

The Material Controller Scripting Language (MCSL) is a simple language that lets you perform basic mathematical expressions evaluation and conditional and direct assignations. The language is made of global variables, numerical constants and operations.

A program is a list of expressions each one separated from the previous by a ';' character.

An expression is always made of 'variable = expression body'.

The language is not case sensitive. A variable can be of any of the following types: scalar (floating point value), four-dimension vector or pointer.

A material controller is made of explicit properties (RED::IMaterialControllerProperty), each one with its own script, and an implicit execution context. The execution context lists all the global variables that can be used in a script running in that context. By default, some constant variables are accessible to every execution context and are detailed later in this document. Each time you add a property to a material controller, a variable with the same name and type as the property is created and added to the controller execution context. Later, when you modify a material controller property value, the value of the associated variable is modified accordingly and the property script is executed. The purpose of this language is to let you access shader configurations and values modifying them accordingly to the user input.

The Writing material controller properties tutorial describes how to create material properties and write corresponding script.

Variables

The syntax of variable name is the following: name(|filter)(.fieldSelector);
where name can refer to:

Example:

assume that we have a controller to a material having several shaders using multiple scalar parameters called 'myParameter'. By executing the script

myParameter = 0.5

All the occurrences of shader parameters having the name 'myParameter' will be assigned the 0.5 value. Let one of the material shaders be called 'myShader'. We can limit the effect of the previous script to that shader only by entering

myShader.myParameter = 0.5

In that case, '.myParameter' acts as a field selector for 'myShader'. An optional filter can be given prefixed by the pipe ('|') character. It can only be applied to a variable whose the name references a shader. If supplied, it must references a valid target for that shader.

myShader|156.myParameter = 0.5

Now modifies the shader parameter called 'myParameter' of the shader 'myShader' for the shader targets combination 156 only.

The optional field selector can also be used to select a single component of a vector or color value. Use '.x', '.y', '.z' or '.w' to select one of the four dimension of a vector4 variable. In the same way, use '.r', '.g', '.b' or '.a' to select one of the four component of a RGBA color.

4x4 matrices can also be modified using one of the following selectors:

Other selectors exist for the special case of accessing shader render codes (see From geometry data to rendering programs). They are:

rcVertexChannel
rcUserChannel#0
rcUserChannel#1
rcUserChannel#2
rcUserChannel#3
rcUserChannel#4
rcNormalChannel
rcColorChannel
rcTexChannel#0
rcTexChannel#1
rcTexChannel#2
rcTexChannel#3
rcTexChannel#4
rcTexChannel#5
rcTexChannel#6
rcTexChannel#7

Each one gives access to a specific binding inside a render code.

An additional field selector is provided to access the local binding of the render codes. It is written 'rcLocal' where index is the index of the render code local binding.

Last but not least, keywords exist to directly access state shader fields. At the moment only the 'transparColor' field selector is available to read and/or write to a state shader transparency color.

Note:

Warning: material controller property names can have spaces (ex: 'Diffuse texture'). In that case, you should insert double quote characters at the beginning and at the end of the variable name in the script:

myShader.diffuse = 'Diffuse texture'

Handling mismatching types in assignment

It can arise that mismatching types are used during variable assignment. In order to add flexibility to the MCSL, some special cases are implicitly handled using the following rules:

Material controller scripting language reference

Here is the complete reference for the Material Controller Scripting Language. For each keyword, the syntax and number and type of the parameters are detailed. scalar, vector4 and pointer refer to the corresponding types. x, y, z, and w refer to the vector4 type components. When needed, examples are given.

Mathematic operatorDescription
'+': arg1 + arg2 or +arg1Addition or unary positive operator: depending on the expression precedence solving, this operator can be considered as a two components addition or as the unary positive operator. In case of an addition, the following configurations are allowed:
Case 1:
  • arg1: scalar
  • arg2: scalar
  • result: scalar = arg1 + arg2
Case 2:
  • arg1: vector4
  • arg2: vector4
  • result: vector4 = { arg1.x + arg2.x, arg1.y + arg2.y, arg1.z + arg2.z, arg1.w + arg2.w }
'-': arg1 - arg2 or -arg1Subtraction or unary negative operator: depending on the expression precedence solving, this operator can be considered as a two components subtraction or as the unary negative operator. In case of a subtraction, the following configurations are allowed:
Case 1:
  • arg1: scalar
  • arg2: scalar
  • result: scalar = arg1 - arg2
Case 2:
  • arg1: vector4
  • arg2: vector4
  • result: vector4 = { arg1.x - arg2.x, arg1.y - arg2.y, arg1.z - arg2.z, arg1.w - arg2.w }
'*': arg1 * arg2Multiplication:
Case 1:
  • arg1: scalar
  • arg2: scalar
  • result: scalar = arg1 * arg2
Case 2:
  • arg1: vector4
  • arg2: scalar
  • result: vector4 = { arg1.x * arg2, arg1.y * arg2, arg1.z * arg2, arg1.w * arg2}
Case 3:
  • arg1: vector4
  • arg2: vector4
  • result: vector4 = { arg1.x * arg2.x, arg1.y * arg2.y, arg1.z * arg2.z, arg1.w * arg2.w }
'/': arg1 / arg2Division:
Case 1:
  • arg1: scalar
  • arg2: scalar
  • result: scalar = arg1 / arg2
Case 2:
  • arg1: vector4
  • arg2: scalar
  • result: vector4 = { arg1.x / arg2, arg1.y / arg2, arg1.z / arg2, arg1.w / arg2}
Case 3:
  • arg1: vector4
  • arg2: vector4
  • result: vector4 = { arg1.x / arg2.x, arg1.y / arg2.y, arg1.z / arg2.z, arg1.w / arg2.w }
'(' and ')'Precedence operators: users can use any number of parenthesis (as long as they are correctly paired) to define to order of evaluation of the mathematical expressions.
'=': arg1 = arg2Assignment operator: copy the value of arg2 into arg1. Both arg1 and arg2 are evaluated before assignment occurs.
'cos', 'sin', 'tan' and 'rad'Trigonometric operators: in MCSL, trigonometric operations use values in radians.
Example #1: a = cos 0.5 // cosine of 0.5 radians
Example #2: a = cos( 0.5 ) * 2 // cosine applies only to 0.5
Example #3: a = cos rad 90 // rad converts 90° to an angle in radians before applying the cosine operator
'sqrt': sqrt arg1Square root: compute the square root of a scalar value
arg1: scalar (must be >= 0) result: scalar = sqrtf( arg1 )
'sqr': sqr arg1Squared: compute the squared value of a scalar input
arg1: scalar result: scalar = arg1 * arg1
'exp': exp arg1Exponential: computes the exponential of a scalar input
arg1: scalar result: scalar = exp( arg1 )
'log': log arg1Logarithm: computes the logarithm of a scalar input
arg1: scalar (must be >= 0) result: scalar = log( arg1 )
'^': arg1 ^ arg2Power: computes the power of a scalar input by another
arg1: scalar arg2: scalar result: scalar = pow( arg1, arg2 )
Miscellaneous operatorDescription
(?:): exp1 ? caseTrue : caseFalseTest operator: evaluate exp1 and then evaluate caseTrue or caseFalse depending on the result of evaluating exp1. If the evaluation of exp1 returned 0, then caseFalse is evaluated, otherwise caseTrue is evaluated.
'intensity': intensity arg1Color intensity: returns the intensity of a color parameter defined as:
( arg1.r + arg1.g + arg1.b ) / 3.0

A small set of constants is globally defined for every running script. Those constants can be freely accessed from within a script for expression writing simplification.

Note:

Warning: the constant names are case sensitive

ConstantValue
'identity'Identity matrix: useful to initialize a transformation matrix before modifying it.
'pi'Pi constant: 3.141592653589
'white', 'black', 'grey', 'red', 'green' and 'blue'Default colors

Finally some miscellaneous keywords are reserved by the scripting language.

KeywordUsage
referenceGives access to a RED engine reference. Supported reference are:
  • 'autoCubeMap': reference to the material auto cube map; example: shader.reflection_texture = reference.autoCubeMap
transparColorField selector for a state shader: read/write the state shader transparency color Example: myStateShader.transparColor = white
transparModeField selector for a state shader: read/write the state shader transparency mode. Currently only RED::StateShader::NO_TRANSPARENCY and RED::StateShader::SORTED_TRANSPARENCY modes are supported.
blendingModeField selector for a state shader: read/write the state shader blending mode.
blendingEquationField selector for a state shader: read/write the state shader blending equation.
blendingFunction1Field selector for a state shader: read/write the state shader blending function #1.
blendingFunction2Field selector for a state shader: read/write the state shader blending function #2.