MeshStandardMaterial, per Texture Tiling

Hello everyone,
I recently faced the necessity of applying different tile (Repeat) to Texture(s) on the same MeshStandardMaterial.
Digging a bit it seems that there is no native support for this use-case in threejs so I decided to follow a DIY approach.
I would like to share what I created to help people in the same situation, and also to collect feedback on potential drawback of my approach, or suggestions for improvements.

Here the specific usecase I had to solve:

(Click on the model to open material’s settings)

To make that model as lite as possible I decided to use a png with alpha as diffuse map (map) in order to create all the holes in the frame.
ThreeJs standard approach makes mandatory to also create 1:1 normal, metalness and roughness maps, making glb itself too heavy.

So i created a piece of code that modify the MeshStandardMaterial using the onBeforeCompile moethod. I did some tests and seems to perform correctly also with different combinations of maps:

Here some examples:

This approach seems to be not invasive from a “code flow” point of view and allows the correct visualization of GLTF that uses the KHR_texture_transform extension (only for the scale, ofcourse).

There are some limitations:

  1. The tile value is bound to the Texture.repeat value, meaning that if 2 maps share the same texture they also share the tile (metalroughness in GLTF for example)
  2. No offset/rotation support
  3. Maybe some overhead for the shader.replace calls
  4. Supports only map, normalMap, metalnessMap, roughnessMap and emissiveMap (AO, LIGHTMAP, ALPHA still share vUv2 with 1:1 tile)
    n) … ?

Here the link to the code:

Is written in typescript.

Example of Typescript usage:

import { addSupportForCustomTiles } from "path/to/CustomTiles.ts";

Example of use with GLTFLoader:

gltfLoader.load(src, (gltf) => {
	gltf.scene.traverse((obj) => {

  			if (obj instanceof Mesh){


Looking forward for feedbacks, Thanks.

1 Like