0

I'm trying to create a decal on my mesh using three.js and react-three-fiber. I believe I correctly set up the mesh and material but for some reason the decal is not showing up on the canvas.

enter image description here

This is the parent component that holds both the model, backplate, and decal.

<Canvas camera={{ position: [0, 0, 2], fov: 70 }}>
    <Lights />
    <Suspense fallback={null}>
        <Model flipped={flipped} returnMesh={setMesh} />
        <Decal mesh={mesh} />
        <Back />
    </Suspense>
</Canvas>

This is part of the component where I create the t-shirt mesh from a .glb file. The mesh is passed back to the parent and then to the Decal component.

let geometry, material, mesh;

// GEOMETRY
geometry = useGLTF("/tshirt.glb").nodes.tshirt.geometry;

useEffect(() => {
    material = new THREE.MeshStandardMaterial({ color: "orange" });
    mesh = new THREE.Mesh(geometry, material);
}, []);

This is how I am trying to set up the decal mesh:

extend({ DecalGeometry });

const Decal = ({ mesh }) => {
    let decalGeometry;

    useEffect(() => {
        if (mesh) {
            decalGeometry = new DecalGeometry(
                mesh,
                new THREE.Vector3(0, 0, 0),
                new THREE.Euler(0, 0, -1, "XYZ"),
                new THREE.Vector3(0.5, 0.5, 0.5)
            );
        }
    }, [mesh]);

    return (
        <mesh geometry={decalGeometry}>
            <meshStandardMaterial attach="material" color="red" />
        </mesh>
    );
};

I am getting no errors, the decal just doesn't appear. I hope someone has some insight. There isn't a lot about Decal Geometry with threejs out there, even less specific to r3f.

Max
  • 754
  • 8
  • 24
  • I'm not sure what you mean. This is another question of mine but even though they concern the same project, they don't have much in common otherwise. – Max Mar 17 '21 at 09:40
  • 1
    I see. Unfortunately I have no answer to either of the questions, yet. As far as I understand, they are quite different. One is about a mesh not showing up, the other is about the rotation matrix of a mesh not being updated. – Max Mar 17 '21 at 09:45
  • do you have a github repo by any chance ? thanks ! – Kevin Gilbert Jun 26 '22 at 10:07
  • 1
    Hi @KevinGilbert, I don't have a minimal reproduction of this right now since the issue is rather old. However, feel free to poke around the repo with the working code: https://github.com/maxibenner/teeshot – Max Jul 06 '22 at 17:50

1 Answers1

1

You are using decalGeometry before it is assigned. This is because callbacks given to useEffect are executed after Decal is called.

Suggested fix: use the useMemo hook.

e.g.

extend({ DecalGeometry });

const Decal = ({ mesh }) => {
    const decalGeometry = useMemo(() => {
        return new DecalGeometry(
            mesh,
            new THREE.Vector3(0, 0, 0),
            new THREE.Euler(0, 0, -1, "XYZ"),
            new THREE.Vector3(0.5, 0.5, 0.5)
        );
    }, [mesh]);

    return (
        <mesh geometry={decalGeometry}>
            <meshStandardMaterial attach="material" color="red" />
        </mesh>
    );
};