Normal Map Not working

Hi, I’m trying to add normalMap but what I get is this:

image

I don’t know if there are any mistakes. I’ve shared what I’ve tried

const normalMap = textureLoader.load(
        "./assets/resources/Water_2_M_Normal.jpg"
      );
      normalMap.wrapS = THREE.RepeatWrapping;
      normalMap.wrapT = THREE.RepeatWrapping;
      model.traverse((mesh) => {
            if (!mesh.isMesh) return;

            var oldMaterial = mesh.material;

            mesh.material = new THREE.MeshPhongMaterial();

            THREE.MeshBasicMaterial.prototype.copy.call(mesh.material, oldMaterial);
            mesh.material.normalMap = normalMap;
          });

When I apply the same for mesh.material.map, it works fine, and for mesh.material.envMap there are no appearance changes. I would like to know What can be improved in this.

Thanks,
Binoy

This will depend a lot on the mesh and the material. Can you share a demo?

Make sure that the mesh has vertex normals and UVs. E.g. print mesh.geometry.attributes, check that there are “normal” and “uv” entries there. Without vertex normals and UVs, a normal map will not work.

If you’re loading a glTF model, you’ll also want to set texture.flipY = false to match the texture coordinate convention.

Finally, if you skip the MeshBasicMaterial.prototype.copy line and just assign the normal map to a new material, does the normal map work?

@donmccurdy, when I checked my gltf files, the mesh.primitives.attributes has only position and normal. Is UV added in TEXCOORD_0?

No, the normalMap didn’t work when I skipped the MeshBasicMaterial.prototype.copy line and assigned normalMap to the new material

The vertex attribute “TEXCOORD_0” in glTF is equivalent to the “uv” attribute in three.js. If this is missing then normal maps (or most other maps, for that matter) will not work. Your mesh will need to be UV unwrapped, usually this is done in tools like Blender.