How to make textures align across adjacent objects

Hi,

I’m trying to make the textures of adjacent objects align.
One object is an imported gltf model, and the other is a programmatically created BoxGeometry.
I tried to match the textures using the material repeat and offset values using a grid debug texture. And this worked but when I resize one of the objects the textures are no longer aligned.
Is there a material or setting that could fix this, something like projecting the material onto the objects in world space?

Example of the issue,
This example has three separate objects. When I change the height of the objects by moving the vertices up, the texture no longer aligns.
image

Second example,
Same setup as before, but now before resizing objects with a debug texture (material repeat and offset values adjusted)
image

Is there a solution currently, without coding a custom shader material? Nope.

But if you can wait a moment - TSL finally introduces triplanar mapping as texture mapping option, which is pretty much exactly what you’re looking for.

1 Like

Hi Mjurczyk,

I’ve been testing around with TSL triplanar texture. And it works partially, the texture is being displayed. But its position seems to stick to the object instead of world space. Am I missing something here?

Expected effect:
expected_result

Result:
triplanar

Current material code:

const material = new MeshStandardNodeMaterial();

const textureMap = new THREE.TextureLoader().load('./texture.jpg');
textureMap.wrapS = THREE.RepeatWrapping;
textureMap.wrapT = THREE.RepeatWrapping;
const colorTexture = texture(textureMap)
material.colorNode = triplanarTexture(colorTexture, colorTexture, colorTexture, 0.5)

const normalTextureMap = new THREE.TextureLoader().load('./normal.jpg');
normalTextureMap.wrapS = THREE.RepeatWrapping;
normalTextureMap.wrapT = THREE.RepeatWrapping;
const normalTexture = texture(normalTextureMap)
material.normalNode = normalMap(triplanarTexture(normalTexture))

Just a small update, after going through the source code I managed to find the code to get the desired effect to work :ok_hand:.

Updated material code:

const material = new MeshStandardNodeMaterial();

const textureMap = new THREE.TextureLoader().load('./texture.jpg');
textureMap.wrapS = THREE.RepeatWrapping;
textureMap.wrapT = THREE.RepeatWrapping;
const colorTexture = texture(textureMap)
material.colorNode = triplanarTexture(colorTexture, colorTexture, colorTexture, 0.5, varying(modelWorldMatrix.mul(positionLocal).xyz, 'v_positionWorld'))

const normalTextureMap = new THREE.TextureLoader().load('./normal.jpg');
normalTextureMap.wrapS = THREE.RepeatWrapping;
normalTextureMap.wrapT = THREE.RepeatWrapping;
const normalTexture = texture(normalTextureMap)
material.normalNode = normalMap(triplanarTexture(normalTexture, normalTexture, normalTexture, 0.5, varying(modelWorldMatrix.mul(positionLocal).xyz, 'v_positionWorld')))

Result:
triplanar2

1 Like

It’s possible to use positionWorld instead of doing the calcs manually.

1 Like