Apply text over a mesh

In the project I’m working there is a feature where you can apply text in some specific areas of the model, like in this picture:

For the time being we are creating a canvas fusing the texture with the text and then applying that canvas. That for me seems like too much work and therefore I’m here asking for your help.

Is there a better way to just apply a transparent canvas with only the text on top of the other textures?

Using an instance of THREE.CanvasTexture seems absolutely fine for this use case.

And What channel should I use to apply this new texture without losing the others?

I would use it in combination with DecalGeometry.

https://threejs.org/examples/webgl_decals

3 Likes

Hi @Mugen87, thank you very much for your suggestion, it gave me the right direction. At this point I’m just trying to figure out how to build the canvas to apply correctly the text, if you have any other advice over this I would appreciate it.


Also you see that the texture is using white background, any idea why?

This is what I’m doing so far:

const decalGeometry = new DecalGeometry(
  mesh,
  new Vector3(1, 8.9, 1.1), // position
  new Euler(), // orientation
  new Vector3(10, 0.5, 3) // size
);
decal = new Mesh(decalGeometry, new MeshPhongMaterial());
decal.position.z += 0.1;
scene.getObjectByName('CFX_PRO').add(decal);

textCanvas = document.getElementById('texttest');
if (!textCanvas) {
  textCanvas = createCanvas(textMonogrammingInfo.canvasData);
  textCanvas.id = 'texttest';

  document.querySelector('.configure-display-container').prepend(textCanvas);
}

const ctx = textCanvas.getContext('2d');
ctx.font = '30px Arial bold';
ctx.textAlign = 'center';
ctx.fillStyle = 'blue';
ctx.fillRect(0, 0, textCanvas.width, textCanvas.height);

ctx.strokeText('1234567890', textCanvas.width / 2, textCanvas.height / 2);

const texture = new CanvasTexture(textCanvas);
console.log(texture);
decal.material.map = texture;

Also you see that the texture is using white background, any idea why?

Maybe try setting material.transparent = true?