# Material Script .MTL

by Christoph Kubisch

## Content

- Definition
- Example
- Stages
- Commands
- Modifiers
- Controllables
- More Examples
- History

## Definition

A material consists of a Shader (the way textures are combined) and texture/color information, it also allows to animate certain sequences of colors or textures and there are also modifiers to animate parameters automatically.

In general a material is loaded whenever you directly apply it to a rendered surface. But it can also be used as "hi-detail" version of a general texture. That means the application will look for the material with same name first, if no material available it will just use the texture.

A material is always bound to a single texture.

All commands are case sensitive and closed by ; !
<id> ranges from 0 to 7
<sid> ranges from 0 to 3
<vector4> is (float,float,float,float)
<bool> is 1 = true, 0 = false

The header is necessary
current version:
luxinia_Material_v100

### Branching

You can do branching with following commands. Enclose the branches in curly brackets { }

- IF:<condition string>
- ELSEIF:<condition string>
- ELSE

The condition string can be set from luxinia API with resource.condition.
You can also negate a statement with !<condition string>.
Be aware that the parser is not fully rock solid, so at best use COMMAND{<newline> <what><newline> }<newline> , when problems occur.

Content

## Example

     luxinia_Material_v100
    # this is a comment
    Shader{
    	SHD "shaders/simple.shd";
    	alpha (0.5);
    }
    Color:0{
    	IF:BLAH{
    		RGBA (1.0,1.0,0.0,1.0);
    	}
    	ELSE{
    		RGBA (0.0,0.0,1.0,1.0);
    	}
    }
    Texture:0{
    	TEXALPHA "textures/blah/foo.tga";
    }
    Texture:1{
    	frames	5;	delay	20;	loop 3;
    	TEX "textures/blah/anim01.tga";
    	TEX "textures/blah/anim02.tga";
    	TEX "textures/blah/anim03.tga";
    	TEX "textures/blah/anim04.tga";
    	TEX "textures/blah/anim05.tga";
    }
    Texture:2{
    	TEX "blubb.jpg";
    	texscale (2,2,1);
    }

Content

## Stages

Shader:<sid>

if no <sid> is passed 0 will be used
<sid> = 0 is the default shader, it is used most time
<sid> 1,2,3 can be enabled for use with l3dview.shaderstage from within your gamecode

- SHD "shadername.shd";
  the shader that is used for this material. be sure you have specified all necessary color/tex ids
- alpha (<float>);
  overrides shader's alphatest value
- param "name" <vector4>;
  overrides shader's param value

Color:<id>

- RGBA <vector4>;
  just a simple color
- Sequence:
  you must specify (frames, delay, loop) first if you want this color to have a sequence !
  - frames,delay,loop
    see Texture
  - interpolate;
    the colors will be linearly interpolated between frames

Texture:<id>

- a single texturemap:
- TEX "filename.jpg";
  - TEX : RGB/RGBA
  - TEXALPHA: ALPHA
- System needs cubemap support:
  - TEXPROJ: RGB/RGBA with cubemap using given texture as +Z
  - TEXDOTZ: INTENSITY/RGB/RGBA with cubemap using given texture as dot(vector,+z), -1 is left and +1 is right.
  - TEXCUBE: 6 textures separated by comma make this texture
    "pos_x.jpg,neg_x.jpg,pos_y.jpg,neg_y.jpg,pos_z.jpg,neg_z.jpg"
    or a single .dds file "cubemap.dds"

- User textures:
  - if the name string looks like "USER_TEX(name)" then the engine will lookup
    user-created textures or registered textures with this name.
    E.g this way you could create a material that uses
    TEX "USER_TEX(ground)" and 'ground' is registered via code to be any other
    texture e.g grass.jpg or sand.tga...

- Special Textures:
  the textures are created and enabled thru FrameFX? system, which is done via scripting/code, so in case you forgot to enable them, you will get garbage.

  - FRAMEFX_CURRENT;
    current framebuffer
  - FRAMEFX_LAST;
    last 3d final image
  - FRAMEFX_SNAPSHOT;
    user defined image of scene

- Sequence:
  you must specify (frames, delay, loop) first if you want this texture to have a sequence !
  - frames <uint>;
    number of files in the sequence, must be defined before items
  - delay <uint>;
    delay between sequences in milliseconds
  - loop <uint>;
    how often the sequence is repeated
    0 played once, 1 played twice,... 255 = played infinetely

Content

## Commands

After the stage specific commands there is multiple possibilities to change the stage, following functions are optional.

### texture functions:

all floats are in texture size: 1.0 = full length/width of a texture
if any texmatrix command is called texscale,texrotate... commands will show no effect

- texmove (<x float>,<y float>,<z float>);
  to move the texture coordinates
- texrotate (<x float>,<y float>,<z float>);
  degrees (clockwise) to rotate them
- texscale (<x float>,<y float>,<z float>);
  to scale the coordinates, values > 1 will result into repeating textures
- texcenter (<x float>,<y float>,<z float>);
  sets a different origin than 0,0,0 for the above operations

- texmatrixc0 (<x float>,<y float>,<z float>,<w float>);
  sets texture matrix column for x (matrices are stored column major)
- texmatrixc1 (<x float>,<y float>,<z float>,<w float>);
  sets texture matrix column for y (matrices are stored column major)
- texmatrixc2 (<x float>,<y float>,<z float>,<w float>);
  sets texture matrix column for z (matrices are stored column major)
- texmatrixc3 (<x float>,<y float>,<z float>,<w float>);
  sets texture matrix column for translation (matrices are stored column major)

- texconst (<R float>,<G float>,<B float>,<A float>);
  texture constant color, for some manual blending
- texclamp (<X bool>,<Y bool>,<Z bool>);
  texture clamping (to edge) enabled for given axis. By default all are off and therefore set to repeat

- sunscreenmatrix;
  generates special shifting so that sun position matches uv center in screenspace (user should use screenmap in shader)

### Sequence functions:

Additionally to the mandatory you can specify these

- wait <uint>;
  wait time in ms between loops
- reverse <uint>;
  every nth time the sequence is played the play direction is changed, ie. 1 would be pingpong

Content

## Modifiers

Modifiers are applied to the next function that takes the specified arguments (float). If the next function does not take such arguments the modifier will be ignored.
Modifiers will be interpolated or not as by user request. Some values are changed every frame, others are only "looked at" when used, the modifiers will interpolate accordingly.
Be careful and do not use too much of them. Modifiers are not allowed for sequence items.

floatmod "<name>" <type> <delay int> (<value float>) <cap uint> <arg uint>;
to modify a value over time

- name
  modifier name, should be unique
- type
  ADD, SIN, COS or ZIGZAG
- delay
  delay in ms between actions
  > 0 interpolation takes place every frame
  < 0 no interpolation is done per frame
  0 hell what do I know hehe
  SIN/COS/ZIGZAG: means the length of a full phase
- value
  - ADD
    out = source += value
  - SIN/COS/ZIGZAG
    out = source * SIN/COS/ZIGZAG + value
- cap
  - ADD
    0 then it will fall back to opposite of clamped source
    1 it will reverse
    2 it will stop
  - SIN/COS/ZIGZAG
    0 perform all values
    1 it will clamp to values > 0
    2 it will clamp to values < 0
- arg
  to specify the argument it should affect in a following function
  0 = first, 1 = second ...

### Notes:

ZIGZAG is linearly pending between -1 and 1 ///
Be aware an ADD on a unclamped source can never be made to stop, only by turning all modifiers of the stage off.
If source value is clamped values above/below will be ignored and maximum/minimum used.

Content

## Controllables

They can be accessed via FunctionPublishing? code and can be made unique per object instance using this material.
control will override floatmods

control "<name>" <arg uint> <length uint>;

- name
  must be unique
- arg
  to specify the argument it should affect in a following function
  0 = first, 1 = second ...
- length
  optionally (default = 1) maximum 4, depending on controlled value
  this way you can control a vector of arbitratry length

Content

## Further Examples

Color:0{

floatmod "test" ZIGZAG 500 (-1.0) 1 3; RGBA (1.0,1.0,1.0,1.0);

}

Alpha value changes starting from 0 to 1 to 0.. linearly every 250ms 1 is reached because 500 would be for a full cycle but we flip values if below 0 hence double frequency

Color:0{

frames: 3; delay: 2000; loop: 255; RGBA (1.0,0.0,0.0,1.0); RGBA (1.0,1.0,0.0,1.0); RGBA (0.0,1.0,0.0,1.0); wait 30000; reverse 1;

}

this would result into a traffic light effect, 30 seconds of leadfoot action likely even a bit more if taking the 2seconds of yellow phase ;)

Texture:0{

TEX "textures/foo/blubb.jpg"; floatmod "shifter" ADD 1000 (0.5) 0 0; texmove (0.0,0.0,0.0);

}

Here we make a scrolling texture which is moved by half of it in a second along its X axis (sideways).

Content

## History

1st Draft 24.2.2005:
Shaders were split into "shaders" and material. mostly a pure branching of functionality

2nd Draft 11.5.2005:
rotation is 3d now

3rd Draft 21.5.2005:
added tile-based texturing

4th Draft 4.6.2005:
added texcenter function to offset the origin for the other operations

5th Draft 15.6.2005:
controllables are added

6th Draft 28.12.2005:
USER Textures added

7th Draft 2.12.2005:
multiple shaders added

8th Draft 27.5.2006:
added .dds support

9th Draft 28.7.2006:
texture clamping

10th Draft 10.8.2006:
added "preprocessor" branching

11th Draft 2.9.2006:
removed sky/cloudmatrix

12th Draft 19.12.2006:
controllabes now can have an optional length parameter texmatrixcolum commands added

Content