Texture Modding

Note: this page concerns OpenMW 0.36.1 and earlier. In OpenMW 0.37, the graphic engine was rewritten using OpenSceneGraph, but the object shaders (which handle the normal maps and specular maps described on this page) have not been ported to this new graphic engine yet.

= Objects =

NIFs
NIFs are unfortunately a bit limited in that they don't allow specifying material properties (such as a bump map) externally, meaning that after creating a bump map for a color texture you'd usually have to edit all meshes that use this texture and distribute the meshes with your mod.

With OpenMW, there is an alternate way:

Material overrides

Create a file called material-overrides.cfg and place it in one of the following locations:

- Windows:  - Linux: /etc/openmw or build folder for a local build - Mac: ?

The file must be a simple INI file. For each base texture, a list of overrides can be specified.

The base textures (INI sections) must be in all lowercase.

[textures\tx_hlaalu_wall2_01.dds] normalMap = textures\tx_hlaalu_normal.dds specular = 1 1 1 64

The full list of override keys can be found in the objects.mat file.

Normal mapping
If using material overrides, use a 'normalMap = ' line. You can also edit meshes and assign the normal map to the BumpTexture slot of the NiTexturingProperty.

Parallax
Parallax mapping requires height information being stored in the normal map's alpha channel. To tell OpenMW that height information is available, make sure your normal map filename contains "_nh." (stands for normalHeight). Example: Tx_BM_snow_01_nh.dds

Please note that the strength of the parallax effect is not globally adjustable at the moment. However, to reduce the effect you can simply scale the heights. Height 0.5 is the base level where no view dependent offset is performed.

Specular
First, make sure that specular is enabled in general.

If using material overrides, add this line:

specular =     RGB is the specular color and S is the shininess.

Example: specular = 1 1 1 64

If editing the mesh:
 * Add a NiSpecularProperty and make sure the 'flags' field is set to '1'.
 * In the NiMaterialProperty, make sure the specular color is set properly and glossiness is valid.

Shininess/glossiness
Valid shininess values are from 1-128. Values higher than 128 may work, but are not supported on all graphics cards. The higher the shininess, the 'sharper' the specular effects will look.

Specular mapping
Specular maps allow variations in specular along the texture of the object. There are two possible ways to do specular mapping:

Diffuse alpha channel

Unless a separate specular map is used (see below), the alpha channel of the diffuse texture will act as a multiplier for the specular color.

Separate specular map

You can also create a new texture and use it as a specular map. In this case, RGB will be used as a multiplier to the specular color and the alpha channel as a multiplier to the shininess value.

This method will cost some performance, since an additional texture must be sampled.

The material override for this is 'specMap':

[textures\tx_hlaalu_wall2_01.dds] normalMap = textures\tx_hlaalu_normal.dds specular = 1 1 1 64 specMap = textures\specular_test.tga

Native format
We plan to have native mesh/material formats in the future, but this is still in the planning stages.

= Terrain =

Specular mapping
For performance reasons, the specular information is stored in the alpha channel of the color texture.

Since Morrowind's vanilla textures are not supposed to have specularity, you need to create a specular-mapped texture with a "_diffusespec" postfix, to indicate that specular information is available for this texture.

For example, for the TX_BM_snow_01.dds layer, a diffuse-specular map would be called TX_BM_snow_01_diffusespec.dds.

Normal mapping
Normal maps need to be named with an _n postfix. For example, for a color texture Tx_BM_snow_01.dds, OpenMW will look for a normal map called Tx_BM_snow_01_n.dds.

Parallax mapping
Parallax mapping requires height information being stored in the normal map's alpha channel. alpha = 1 -> highest, alpha = 0 -> lowest.

Also, the filename postfix you need to use becomes _nh (e.g. Tx_BM_snow_01_nh.dds) so that OpenMW knows that height information is available.