From TrainzOnline
Jump to: navigation, search

m.clutter is a variation on the m.pbrmetalmasked material. It adds controlled fade distances which are intended to allow cross-fading between LODs. It does not include support for parallax mapping. All PBR materials are defined using a multitude of texture channels (not just a simple RGB image) which define various aspects of the material on a per-texel basis. One major advantage of this approach is that a single in-game material can be used to display various different real-world materials, rather than requiring multiple separate in-game materials with different parameters. Trainz uses a Metallic/Roughness style PBR workflow.

This material is intended for use with the Clutter Effect Layer, and is tuned to suit that purpose to the detriment of any other possible use-case. While it is permissible to use the material with non-clutter asset types, we reserve the right to make changes to the behaviour of the material in ways that do not impact negatively on the clutter effect layer usage, even where those changes negatively impact other uses. For this reason, and because performance of an m.clutter asset is likely to be lower than an equivalent m.pbrmetal asset, it is recommended that m.clutter is used for a non-clutter asset only where substantial performance and visual gains are possible which cannot be achieved using other techniques.

This page describes content format v4.6 and assumes that the FBX file format is used as a data source for any meshes.



An example video of a crossfade clutter asset can be found HERE.

Cross-fading is expected to increase the cost of each LOD, but improve the visual transitions. The intent is that transitions can occur much closer to the camera, saving performance overall. If your use-case does not allow transitions to occur close to the camera, you may find that this material type is inappropriate for your needs. The typical use case is something which is small and heavily repeated in the scene, which requires high detail (eg. 100-500 polygons) at very close ranges (eg. up to about 10m) after which it can rapidly lose detail (eg. 500->100->10 or 100->25->5).

Cross-fading is implemented by using two different instances of this material per LOD level; one configured to fade out starting at a certain distance, and the other configured to fade in starting at the same distance. The nearer material is considered a higher LOD and should use more polygons. The asset might then be configured as follows:

  • LOD0 - 0 .. 20m - Material A (no fade in, fade out begins at 10m) using 500 polygons. Material B (fade in begins at 10m, no fade out) using 100 polygons. Totals: 2 materials, 600 polygons.
  • LOD1 - 20 .. 50m - Material C (no fade in, fade out begins at 35m) using 100 polygons. Material D (fade in begins at 35m, no face out) using 20 polygons. Totals: 2 materials, 120 polygons.
  • LOD2 - 50m .. 250m - Material E (no fade in, fade out begins at 200m) using 20 polygons. Totals: 1 material, 20 polygons.

The same asset with a traditional material and no cross-fading might be as follows:

  • LOD0 - 0 .. 50m - Material A using 500 polygons. Totals: 1 material, 500 polygons.
  • LOD1 - 50m .. 150m - Material A using 100 polygons. Totals: 1 material, 100 polygons.
  • LOD2 - 150m .. 400m - Material A using 20 polygons. Totals: 1 material, 20 polygons.


Assuming an object density of one instance per 10m x 10m tile, the two approaches give approximately the following numbers:

  • Cross-faded: 7540 + 7917 + 37699 = 53156 polygons, 5 draw calls (due to 5 materials in use).
  • Traditional: 39270 + 62832 + 86393 = 188495 polygons, 5 draw calls (due to 3 materials in use, two of which require two chunks due to excess vertices).

So while there is an additional overdraw cost from the m.clutter material, there is a 72% saving in polygon count and no practical increase in draw call count. This trend continues as object density increases (which is why this material is important for the Clutter Effect Layer).

In visual terms, the material provides superior LOD transitions without requiring extensive effort on the part of the content creator, making it a very effective technique for improving LOD at low polygon densities where tradition LOD transitions can result in noticeable changes. As polygon count increases, the content creator (and automated LOD tools) are likely to have an easier job of LOD reduction, so the benefits are less meaningful while the increased polygon cost (of effectively having two LODs active at any given time) can be significant.

The cost of using additional materials can be further mitigated by re-using the materials between multiple clutter assets which are likely to be used together, via a texture atlas.

Crossfade Metadata Configuration

As mentioned above, every mesh needs a unique material applied to it in order for crossfading from one mesh to another to work. They can still use the same textures, just the materials need to be unique.

Taking the crossfade example above, this is how you would configure your mesh metadata files:

Once each of the fbx files exist:

lod0.trainmesh - consists of 600 polys and 2 materials (say: materialA.m.clutter and materialB.m.clutter)

lod1.trainmesh - consists of 120 polys and 2 materials (say: materialC.m.clutter and materialD.m.clutter)

lod2.trainmesh - consists of 20 polys and 1 materials (say: materialE.m.clutter)

You'll need to setup the mesh metadata files for each like so. Create each metadata.txt file:




Open lod0.txt and add this text:

     fadeOutEndDistance                20
     fadeInEndDistance		       20

Open lod1.txt and add this text:

     fadeOutEndDistance                50
     fadeInEndDistance	               50

Open lod2.txt and add this text:

     fadeOutEndDistance                250

Texture Slots

The following texture slots are used for this material. All textures should typically have the same dimensions unless they represent a uniform color, however this is not strictly enforced.


RGB: The albedo map defines the base color of each texel. The sRGB color space is used.

A: The alpha channel provides a "black and white" masked alpha channel. Black indicates full transparency, meaning that the fragment is discarded. White indicates full opacity, meaning that rendering proceeds as per m.pbrmetal. If the alpha channel is omitted, this material acts exactly as m.pbrmetal except with lower performance. Note that unlike legacy Trainz materials, PBR materials do not autodetect opacity mode based on the texture in use. The content creator must select the appropriate material for their desired outcome. Runtime texture replacement should not expect to replace an opaque texture with a blended or masked texture and have the material update automatically.

Albedo Texture Example with Alpha

Clutter albedo.jpg Clutter albedo alpha.jpg


RGB: Surface normal map. This defines which way the surface is facing, relative to the interpolated vertex normals. Since this is an XYZ format rather than color data, it should never be modified in Photoshop. Using Photoshop to add a fourth channel or copy/paste smaller textures into a texture atlas is acceptable. Per-pixel manipulation or use of filters on the "RGB" channels is not acceptable.

A: Displacement height. 0.0 represents the deepest possible value, while 1.0 represents the shallowest possible value. While it is possible to paint this data in Photoshop, a linear color space must be used, and far superior results will be available through other data sources. The parallax height and the surface normal must be kept in sync, which means that a third-party tool must be used to generate the surface normal from the parallax height if you are painting this map manually.

Normal Texture Example with no Alpha Channel (Parallax)

Clutter normal.jpg

Normal Texture Example with Alpha Channel (Parallax)

NOTE: This isn't a fern like the rest of the example as the fern texture doesn't benefit from a height map. This is a stump instead. You will notice we have used a very small amount of depth in the height map to give it more depth in the cracks.

Clutter normal height map1.jpg Clutter normal height map2.jpg


This texture is comprised of four separate channels which each form a separate data element. Linear color space (not sRGB) is used for these channels.

NOTE: Because this texture example is a solid colour you will want to make sure it is a 2x2 resolution so you don't waste texture space. This doesn't mean all m.clutter assets need to have (0) zero roughness and (0) zero metallic values, this is just what the example has been configured with.


R: Emissive. This causes the texture to have an internal glow, even when no external light is present. Used for phosphors, permanently-lit markings, etc. The glow color is based on the albedo. Note that this glow does not cast light upon surrounding surfaces except via the Bloom post-processing effect.

Parameters (Emissive - Red Channel) Texture Example


G: Roughness. Defines whether the surface reflections are shiny (0.0) or matte (1.0). See the PBR metal workflow for details.

Parameters (Roughness - Green Channel) Texture Example


B: Ambient Occlusion. Defines whether the surface is exposed to ambient lighting conditions (1.0) or affected only by direct lighting (0.0).

Parameters (Ambient Occlusion - Blue Channel) Texture Example


A: Metallicity. Defines whether the surface is metallic (1.0) with the albedo used to colorize reflected light, or dielectric (0.0) with the albedo used to colorize the surface. While intermediate values are not physically accurate, they may be used to emulate subsurfaces which are partially metallic. See the PBR metal workflow for details.

Parameters (Metallic - Alpha Channel) Texture Example


Many vs. One Clutter Asset Onscreen

Before you start looking at creating assets for Clutter Effect Layers you should have a very good knowledge on how you go about modelling efficient meshes for each LOD level and what textures you should be using for each mesh LOD. You can find an excellent reference on how to model and texture assets under the Modelling Overview on the Art Recommendations Trainz wiki page.

Many Clutter Assets Onscreen

If it's not obvious on that Art Recommendations page; for any large amount of clutter objects you use onscreen at one time, it's best to have at least the lowest LODs (which shouldn't be very far from the camera) using a Texture Atlas. The texture atlas should be as small as can be while maintaining good visual results (256x256 perhaps) and will hold all the images for all the assets lowest LODs. This means when the lowest LODs are showing (which should be the majority of clutter onscreen most of the time) you'll only be paying the cost of 1 material shared across all the lowest LODs. You will also want to share as many single textures between as many assets as possible to cut-down on draw calls where possible - If you have 3 ferns all of different sizes, don't make 3 copies of the same texture.


One or Two Clutter Assets Onscreen

If you are not using a heavy number of assets onscreen at once then you probably don’t need a texture atlas and can get away with single textures per asset. Still worth using a Trainz Mesh Library asset in most cases and sharing as many single textures between as many assets as possible to cut-down draw calls.

Material Attributes

The following attributes may be overridden in the mesh metadata file associated with the material's parent mesh:

  • fadeInEndDistance - A single number (default 0.0) which defines the distance (in meters) at which the material will complete its fade in. If set to zero (default), no fade-in effect occurs and the material remains visible to zero distance. Fade-in begins at 75% of this distance and is complete by 100% of this distance. Fade-in occurs per fragment and is computed on the GPU so does not suffer any update lag when the object changes distances relative to the camera.
  • fadeOutEndDistance - A single number (default 200.0) which defines the distance (in meters) at which the material will complete its fade out. This number should be at least 33% greater than the fadeInEndDistance. Fade-out begins at 75% of this distance and is complete by 100% of this distance. Fade-out occurs per fragment and is computed on the GPU so does not suffer any update lag when the object changes distances relative to the camera.

Please note that there is no performance benefit to a fragment being faded out- the GPU is still required to render each polygon and each fragment touched, even if it is fully faded. In practice, this can also increase the amount of overdraw in the scene, so a fully faded-out fragment may have more performance impact than a fully faded-in fragment.

General Metadata Configuration

If an asset has multiple instances of a material across multiple meshes, it is important to note that this shared material needs to be identical on all meshes and in all mesh metadata file. This is important to note for Mesh Libraries because several meshes in the library will share the same material name. When you import your content into Content Manager, Trainz processes all the meshes and checks to make sure all the meshes using the same material use the same fadeInEndDistance and fadeOutEndDistance values in each of the mesh metadata file. If any of the shared material names have different values in the mesh metadata files you will end up with errors in Content Manager for your asset telling you which assets are conflicting.

Take this for example:

You have a small fern (Fern_Mesh_Small.trainzmesh) and a large fern (Fern_Mesh_Large.trainzmesh) and you want the small one to fade out at 100 meters and the large one to fade out at 300 meters. In order to do this you will need one unique material for each mesh (and in this case, each unique material will still use the same textures, but isn't always the case. You might have different looking meshes that can't share the textures).

Fern_Mesh_Small.trainzmesh will be configured with (say) bodysmall.m.clutter

Fern_Mesh_Large.trainzmesh will be configured with (say) bodylarge.m.clutter

Again, they still use the same textures but the materials need to be unique to each mesh in order to split off the fade distances to Small = 100m and Large = 300m.

Once exported you'll need to setup the mesh metadata files for each like so.

Create each metadata.txt file:



Open Fern_Mesh_Small.txt and add this text:

     fadeOutEndDistance		100

Open Fern_Mesh_Large.txt and add this text:

     fadeOutEndDistance		300



Polygons = 328, Material = 1



Polygons = 121, Material = 1



Polygons = 34, Material = 1



3ds Max Material Configuration

Texture Assignment


Blender Material Configuration


Personal tools