I’m making a tool that also places a logo on some 3D models by mouse click. I have no jurisdiction on the models that will be provided, I have just a sample to work with.
I’ve found that decal is the way to go, but I experienced an unexpected problem: z-fighting.
I imagine decal should be not so problematic as there are few complains about this issue but in my case it is making me lose lots of hours. I’ve tried the most common solutions (renderOrder, renderDepth …) but with no sensible result. This is how it looks (wireframe to show how the same logo should look)
The solution that worked for me is to move the decal mesh up of a 0.001, up… from the surface, so with a known surface orientation it works and I know it can be a good solution.
So my idea was this (the code is derived from the threejs decal example, but with only 1 decal mesh)
this.position.copy(this.intersection.point);
const normalOffset = this.intersection.normal.clone();
normalOffset.multiplyScalar(0.01);
this.position.add(normalOffset);
const material = this.decalMaterial.clone();
if (this.currentDecal) {
this.viewer.currentModel.remove(this.currentDecal);
}
this.currentDecal = new THREE.Mesh(
new DecalGeometry(this.intersection.mesh.object, this.position, this.orientation, this.size),
material
);
this.viewer.currentModel.attach(this.currentDecal);
then I save the position x,y,z in order to recreate the decal when the model is loaded in the products viewer but it doesn’t work even if doing something like this it works.
// this.currentDecal.position.y+=0.001;
this.currentDecal.position.z+=0.001;
this.viewer.currentModel.attach(this.currentDecal);
So I think the intersection normal is not normal to the decal mesh, I made some trials with localToWorld and worldToLocal but there must be something I don’t understand…