Skip to content

Materials and Compiled States (.smt_t and .rw4)

Emd4600 edited this page Apr 1, 2019 · 2 revisions

Materials define the way an object is rendered in the game. All models have at least one material that will tell the renderer which texture, shader, color, etc to use when rendering.

Materials are actually made of:

  • One or multiple compiled states. Compiled states contain most information about the material; usually only one is used, we don't knw what multiple states might be used for.
  • Textures

You can find materials in two places:

  • Inside .rw4 models. There can be more than one material there, and they are called CompiledStates.
  • In .smt_t files, which are part of material packs. Material packs contain all those general materials that are not used in an specific model (for example, water, creature, etc)

.smt_t files

Material packs are stored in the materials_compiled_states_link~ (0x40212000) folder, in a .smt file; when unpacked, they finish with the extension .smt_t. It is possible to create your custom material packs. You can have your own MyMaterials.smt.unpacked folder (where MyMaterials is whatever name you want, unique to your mod) containing material files.

A .smt_t file contains one or multiple compiled states that will be used by your material. Then, it contains only one material instruction that follows this structure:

material ID -states stateNames... -textures textureIDs
  • ID is the exported name of your shader. That will be the ID you have to reference to use this material.
  • At states you must specify the names of the compiled states in the file that the material will use.
  • textures is optional, you can specify the folder and file name (with no extension) of any textures this material requires.

Example of a .smt_t file:

Compiled States

Compiled states are defined with the compiledState block, they take a name as a parameter. The name of the state only affects the file and so it's not really important. They can have the following attributes:


shaderID id

Sets the shader that wil be used to render this material. This is the ID of either an Standard Shader or a Shader Builder.


materialColor colorRGBA

The color of the material, with opacity; when defined, it can be used in shaders with the materialColor shader data. Takes an RGBA ArgScript Color.


ambientColor colorRGB

The ambient color of the material; when defined, it can be used in shaders with the ambientColor shader data. Takes an RGB ArgScript Color.


primitiveType value

Determines the type of primitive used in the model data, generally you don't need to touch this. The value is any of the D3DPRIMITIVETYPE enumeration.


flags1 value

Unknown usage.


flags3 value

Unknown usage.


unkData3 17values

Unknown usage, maybe related with textures. Takes 17 boolean values.

Shader Data

shaderData dataName data...

Compiled states can define Shader Data that will be used when rendering the material. You must specify the name of the data (sometimes it's an hexadecimal number) and then all the values it takes. Unfortunately, values can only be displayed as integers so if you, for example, want to use a floating point number, you will need to convert it beforehand. You can use this instruction multiple times to define more than one data.

Render States

Render States are different variables that affect the rendering pipeline. In a material you can specify multiple render states with this instruction:

renderState name value

You must specify the name, which is any in the D3DRENDERSTATETYPE enumeration. The type of value expected depends on the specific render state.

Rende states can be grouped inside a statesGroup block, which takes an integer as parameter. For example:

statesGroup 0
	renderState D3DRS_SRCBLEND D3DBLEND_SRCALPHA
	renderState D3DRS_DESTBLEND D3DBLEND_INVSRCALPHA
	renderState D3DRS_ALPHABLENDENABLE TRUE
end

Texture Slots

Materials can use textures, those are defined through texture slots. Keep in mind, a slot means that a texture could be used there, but it's not the texture itself. This means taht you can't have two texture slots without assigning them any texture, because maybe the game code will add that texture when using the material.

Texture slots are defined using the textureSlot block, which takes the slot index (starting at 0) as parameter. The block can have the following attributes:

samplerState name value

You must specify the name, which is any in the D3DSAMPLERSTATETYPE enumeration. The type of value expected depends on the specific render state.


stageState name value

You must specify the name, which is any in the D3DTEXTURESTAGESTATETYPE enumeration. The type of value expected depends on the specific render state.


raster objectIndex

Only available in the materials of a .rw4 model. This attribute holds the index of the raster object used as a texture.

Example of two texture slots in a .smt_t file:

textureSlot 0
	samplerState D3DSAMP_ADDRESSU D3DTADDRESS_BORDER
	samplerState D3DSAMP_ADDRESSV D3DTADDRESS_BORDER
	samplerState D3DSAMP_MAGFILTER D3DTEXF_LINEAR
	samplerState D3DSAMP_MINFILTER D3DTEXF_LINEAR
end
textureSlot 1
	samplerState D3DSAMP_ADDRESSU D3DTADDRESS_BORDER
	samplerState D3DSAMP_ADDRESSV D3DTADDRESS_BORDER
	samplerState D3DSAMP_MAGFILTER D3DTEXF_LINEAR
	samplerState D3DSAMP_MINFILTER D3DTEXF_LINEAR
end

Vertex Description

The vertexDescription lock is really important as it defines the elements (e.g. position, normals, UV coordinates, vertex colors, etc) that vertices in the models that use this material must use. Therefore, the vertex description is used to read data from vertices and defines the data that is sent to the shaders.

The vertex description block is made up of multiple element instructions (order is important), which follow this structure:

element type usage shaderUsage -usageIndex int -stream int -method D3DDECLMETHOD

Every attribute must define the shaderUsage and the D3DDECLTYPE of the element. The shader usage is one of the values allowed in the vertex fragments input.

Optionally you can also specify the -method and -stream, although these are rarely used.

Example of a vertex description:

vertexDescription
	element position D3DDECLTYPE_FLOAT3
	element texcoord0 D3DDECLTYPE_FLOAT2
	element texcoord1 D3DDECLTYPE_FLOAT3 
	element color D3DDECLTYPE_D3DCOLOR
end
You can’t perform that action at this time.