What is the best approach for adding text/images to an object

Hey there.

I’ve got an object on which I’d like to add something like a text or an image.
For example: An object with a rough-looking material/texture which has a shiny text on it.

I already have an object with a rough-looking material/texture, but what is the best approach to add a shiny text to it? is decalGeometry the best approach?

Thanks in advance.

Depending on your use case DecalGeometry is one way to project a text onto an existing surface. However, you need to write the text on a texture (e.g. write the text to a 2D canvas and then use CanvasTexture) and then use it as the diffuse map for the decal.

If you need more control over how the text is added to the object, you might want to add the text in a DCC tool like Blender and not at runtime.

Okay, I’ll give it a try. Thanks!

For this example I used a small jpeg (just an image) to project it onto my object but I’m still having trouble.

let decalImage = new THREE.TextureLoader().load(‘Decal/ObjectDecal.jpg’);

            let decalMaterial = new THREE.MeshPhongMaterial({
                map: decalImage,
                transparent: true,
                depthTest: true,
                depthWrite: false,
                polygonOffset: true,
                polygonOffsetFactor: -4,
                wireframe: false
            });

            let decalGeometry = new THREE.DecalGeometry(
                myObject,
                new THREE.Euler(0, 20.5, 30),
                new THREE.Euler(0, 0, 0),
                new THREE.Euler(80, 80, 80),
                myObjectMaterial
            );
            decal = new THREE.Mesh(decalGeometry, decalMaterial);

            scene.add(decal);

I tried to solve the problem using the three.js-documentation but I’m still having trouble.
When I try this code there is this error: Cannot read property ‘geometry’ of undefined

Are there some major problems with the code?

You are not creating DecalGeometry correctly. As mentioned in the docs, the signature is:

constructor( mesh: Mesh, position: Vector3, orientation: Euler, size: Vector3 );

You are using this right now:

constructor( mesh: Mesh, position: Euler, orientation: Euler, size: Euler, myObjectMaterial: Material );

Please try it again with the correct parameterization.

Thank you for the correction.

Now I used the correct parameterization but there is still the mentioned error.

“DecalGeometry.js:62 Uncaught TypeError: Cannot read property ‘geometry’ of undefined
at generate (DecalGeometry.js:62)
at new THREE.DecalGeometry (DecalGeometry.js:43)
at index.html:267
at Object.onLoad (HDRCubeTextureLoader.js:104)
at XMLHttpRequest. (three.min.js:755)”

Any idea what the issue may be?

It seems that myObject does not have a geometry. Can you please verify if it is actually an instance of Mesh.

I loaded my object with the gltf-loader so I did the following:

myObject = gltf.scene;

But I also used it when I traversed:

myObject.traverse(function (child) {
if (child.isMesh) {
and then it continous.

does this verify that it is a mesh or is a step missing?

No, this does look correct! Do you mind demonstrating the issue with a live example?

I’m not sure how to help further without debugging.

It’s hard because the project is a little bit bigger and complex with its paths.

I’m creating my decal components within my gltf-loader-function. May that be a problem?
I thought this would be an easy way to access myObject.

It’s mentioned in the docs as “geo = new DecalGeometry” but “geo = new THREE.DecalGeometry” is the right way i guess?

That depends how you import DecalGeometry. When using ES6 imports (recommended), the usage of the THREE namespace is not necessary.

I assume ES6 imports are the ones that are used in the three.js examples, right ?
With the module

Here is an alternative example of using the DecalGeometry.
https://sbcode.net/extra_html/game.html

View the source. Line 78 in the debugger

This code uses ES6 imports

Correct :+1:. If you are going to implement a real app, I suggest you import the modules from the official npm package and then perform a build (e.g. with rollup) to produce your final app bundle. There are several starter projects that simplify the respective setup. E.g. Module Import / Usage - #26 by seanwasere

Thank you, I’ll give this a try, too.

This sounds good so far.
It may be a pretty rough question -> But what are the main advantages using modules?
I’m not quite sure if I need them, and it sounds a little confusing too.

Unfortunately there is still the problem with my “myObject”.
“Cannot read property ‘isGeometry’ of undefined”

Pretty hard to tell what the problem is.

There are many existing resources answering this question. E.g.

The following resource provides a more in-depth explanation and is a must for all JS developers:

https://exploringjs.com/es6/ch_modules.html

Thanks! I’ll have a look.