Hi everyone,
I’m running into a problem when using DecalGeometry
to place a logo on a mesh after moving its parent group in the scene.
If I apply the decal right after loading the model, everything works perfectly. But when I move the group along the Y axis (e.g. group.position.y += 0.005
) and then call the decal function, the logo appears offset — usually above or below where it should be.
Here’s the rough idea of what I’m doing:
// Move the model up
group.position.y += 0.005;
// Then apply decal
const box = new THREE.Box3().setFromObject(targetMesh);
const center = box.getCenter(new THREE.Vector3());
const decalGeometry = new DecalGeometry(
targetMesh,
center, // ← I suspect this becomes incorrect after moving
orientation,
size
);
const decal = new THREE.Mesh(decalGeometry, decalMaterial);
group.add(decal);
What’s the correct way to position a decal on a mesh after the group or model has been moved?
Thanks in advance!
What does happen if you update the matrix right after changing the position?
group.position.y += 0.005;
group.updateMatrixWorld(); // add this
And also this.
1 Like
Logos should be located like this. But after moving up or down, it looks like below:
Related functions are below:
const moveUp = () => {
if (playerGroup) {
playerGroup.position.y += 0.005
playerGroup.updateMatrixWorld()
camera.lookAt(playerGroup.position)
}
if(goalkeeperGroup) {
goalkeeperGroup.position.y += 0.005
goalkeeperGroup.updateMatrixWorld()
camera.lookAt(goalkeeperGroup.position)
}
controls.update()
}
const moveDown = () => {
if (playerGroup) {
playerGroup.position.y -= 0.005
playerGroup.updateMatrixWorld()
camera.lookAt(playerGroup.position)
}
if(goalkeeperGroup) {
goalkeeperGroup.position.y -= 0.005
goalkeeperGroup.updateMatrixWorld()
camera.lookAt(goalkeeperGroup.position)
}
controls.update()
}
Your suggestion didn’t work.
Maybe it is better to recreate the issue in a way that it could be debugged online. When I try with my code, it works fine, so in your code there might be something else, that is different, but only you can tell this.
Here is my test:
targetGroup.position.y += 5;
targetGroup.updateMatrixWorld( true, true );
const box = new THREE.Box3().setFromObject(targetMesh, true);
const center = box.getCenter(new THREE.Vector3());
var decal = new THREE.Mesh( new DecalGeometry(
targetMesh,
center,
new THREE.Euler( 0.5, -1, 0 ),
new THREE.Vector3( 30, 2, 2) ),
decalMaterial );
Two changes:
updateMatrixWorld( true, true )
is used
setFromObject(targetMesh, true)
is used
The online demo is here: https://codepen.io/boytchev/pen/gbprPqR?editors=0011. See lines 65-76.

By the way, the code above is for the case when the player is moved before the decal is created:
- player is created
- player is moved
- decal is created
If the player is moved after the decal is created, then it should be:
- player is created
- decal is created
- player is moved
- decal is moved
2 Likes