Modular 3D Assets - Texturing

For performance, efficiency, and game size, we rely heavily on trim sheets and reusable textures.

Texture Types we Use

Trim Sheets

Instead of texturing a pillar, a doorframe, and a wall baseboard separately, create one texture sheet that contains tiling strips of wood, stone, and metal trim. Artists map their UVs to this single shared material.

Tileable Textures

Seamless, tileable textures for large surfaces (brick, plaster).

Variation

With just these two types of textures, the games would look very repetitive. To avoid this, we use a handful of techniques.

Vertex Painting

Each vertex holds a color. We have a system that allows applying a texture for each of these color channels (R, G, and B). This means, we can have a base material, and then paint with 3 additional materials on top of it. For example:
Base material is wood, and we can vertex paint damage, stains, and paint onto it.
Vertex colours are authored in Blender, as part of the asset. A kit ships 3–4 pre-varied versions rather than being painted per-instance. In-scene painting is reserved for hero geometry, must be explicitly marked, and is excluded from the batching budget, because a painted instance becomes a unique mesh and loses GPU instancing and static batching.

Additional UV channels

We can use additional UV channels for overlay textures. Position the 2nd or 3rd UVs to align the overlay where you want it, and it is composited over the base material.

Masking the overlay

Where the overlay applies is controlled by the vertex colour alpha channel. 0 means no overlay on that vertex, 1 means full overlay. R, G and B are already carrying material blending (see Vertex Painting), so alpha was free.

This is what new assets use. It has no failure mode at distance, adds no shader variants, and survives GPU instancing, because it is per-vertex data baked into the asset like any other vertex colour.

The older method: a transparent margin

Assets authored before this change mask the overlay by parking unused UVs in a fully transparent right-hand 5% of the overlay texture. It works, and those assets do not need converting, but it fails in ways that are hard to trace. At lower mip levels the transparent margin blends with its neighbours and the overlay ghosts at distance, and any UV slightly outside the range wraps to opaque pixels.

If you do need it (because the mesh is too coarse to carry a useful vertex mask), the texture must import with wrap mode Clamp, and either mipmaps disabled or at least 32 px of transparent padding.

RGB Masking

For modular and reusable assets, color variation is crucial. A striped curtain could be one color combination in one house, and another in the neighbours house. This would mean lots of textures, annoying changes when changing the color theme, etc.
Luckily, there is a solution: RGB Mapping!
The idea is simple. When painting a texture for a model, the artist paints that texture in black and white, only caring about values. Then, another texture is created: The Mask. Each channel (R, G & B) will correspond to a color (Primary, Secondary, Tertiary). In Unity, the Mask is then used to tint the black and white base texture to the per-material defined color based on the mask.
Example:
Pixel is fully red and primary color is purple -> Mesh is purple there.

Heres a great example by @minionsart
Pasted image 20260701193742.png

Damage

Some models might heavily rely on damage. For this, you can supply two additional textures:

  • A Damage Mask (black and white)
  • The damage surface texture(s)
    Then, everywhere the mask is white, the damage surface texture is used instead of the base material one. This could be scraped-off metal on a painted weapon, etc.
    For low-detail damage/big objects, this should be done using one of the Vertex Painting channels, since it is a lot more performance friendly.

Procedural Details, Noise, and Wear

On top of all that, we layer multiple procedural effects, all configured per-material. This can be:

  • Noise (Normal, Smoothness, Brightness)
  • Snow/Puddles
  • Brushstroke Effects
  • etc.