The displayed model color is inconsistent with the original model color

 1. When the model file only has one fbx file, the model texture displayed is different from that seen on the model platform.

2. When there are files in three formats: mtl, obj, and png, the displayed colors are inconsistent with the original model.

const ModelViewer = ({ zipUrl }) => {
  const mountRef = useRef(null);

  useEffect(() => {
    const initScene = () => {
      const width = mountRef.current.clientWidth;
      const height = mountRef.current.clientHeight;

      const scene = new THREE.Scene();
     
      // scene.background = new THREE.Color(0xffffff);
      const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
      const renderer = new THREE.WebGLRenderer({ antialias: true });

      renderer.setSize(width, height);
      mountRef.current.appendChild(renderer.domElement);

      const controls = new OrbitControls(camera, renderer.domElement);

      // Ambient Light with higher intensity
      const ambientLight = new THREE.AmbientLight(0x404040, 2); // higher intensity
      scene.add(ambientLight);

      // Directional Light to simulate sunlight
      const directionalLight = new THREE.DirectionalLight(0xffffff, 2); // higher intensity
      directionalLight.position.set(5, 10, 7.5);
      scene.add(directionalLight);

      // Point Light to add some more brightness
      // const pointLight = new THREE.PointLight(0xffffff, 2, 100); // higher intensity
      // pointLight.position.set(0, 10, 10);
      // scene.add(pointLight);

      camera.position.z = 5;
      controls.update();

      // return { scene, camera, renderer, controls };
      return { scene, camera, renderer };
    };

    const { scene, camera, renderer } = initScene();

    const animate = (object) => {
      // let animationId;
      const render = function () {
        requestAnimationFrame(render);
        // animationId = requestAnimationFrame(render);
        object.rotation.y += 0.01;
        renderer.render(scene, camera);
      };
      render();
      
      // document.addEventListener('click', function() {
      //   cancelAnimationFrame(animationId);
      // });
    };

    const loadModel = async (file, fileType, textureBlob) => {
      let loader;
      const fileBlob = await file.async("blob");
      const fileUrl = URL.createObjectURL(fileBlob);

      switch (fileType) {
        case 'fbx':
          loader = new FBXLoader();
          break;
        case 'obj':
          const mtlFileUrl = getMtlFileUrl(fileUrl);
          const mtlBlob = await fetchMtlBlob(mtlFileUrl);
          const mtlUrl = URL.createObjectURL(mtlBlob);

          const mtlLoader = new MTLLoader();
          mtlLoader.load(mtlUrl, (materials) => {
            materials.preload();
            const objLoader = new OBJLoader();
            objLoader.setMaterials(materials);
            objLoader.load(fileUrl, (object) => {
              applyTexture(object, textureBlob);
              // scene.add(object);
              sizeAndAddModel(object, scene);
              animate(object);
            });
          });
          return;
        case 'gltf':
        case 'glb':
          loader = new GLTFLoader();
          break;
        default:
          console.error(`Unsupported file type: ${fileType}`);
          return;
      }

      loader.load(fileUrl, (object) => {
        applyTexture(object, textureBlob);
        // scene.add(object);
        sizeAndAddModel(object, scene);
        animate(object);
      });
    };

    const sizeAndAddModel = (object, scene) => {
      
      const box = new THREE.Box3().setFromObject(object);
      const size = box.getSize(new THREE.Vector3());
      const targetSize = 4;
      const scale = targetSize / Math.max(size.x, size.y, size.z);

      object.scale.set(scale, scale, scale);
      scene.add(object);
    };

    const fetchMtlBlob = async (mtlFileUrl) => {
      const response = await fetch(mtlFileUrl);
      return await response.blob();
    };

    const applyTexture = (object, textureBlob) => {
      if (textureBlob) {
          const textureLoader = new THREE.TextureLoader();
          const textureUrl = URL.createObjectURL(textureBlob);
          textureLoader.load(textureUrl, (loadedTexture) => {
              object.traverse((child) => {
                  if (child.isMesh) {
                      child.material.map = loadedTexture;
                      child.material.needsUpdate = true;
                  }
              });
          });
      }
    };

    const getMtlFileUrl = (objFileUrl) => {
      return objFileUrl.replace('.obj', '.mtl');
    };

    const fetchAndUnzip = async (url) => {
      const response = await fetch(url.replace(/http:///g, 'https://'));
      const arrayBuffer = await response.arrayBuffer();
      const zip = await JSZip.loadAsync(arrayBuffer);

      let textureFile;
      const modelFiles = [];

      zip.forEach((relativePath, file) => {
        const ext = relativePath.split('.').pop().toLowerCase();
      
        if (ext === 'png' || ext === 'jpg' || ext === 'jpeg') {
          textureFile = file;
        
        } else if (ext === 'fbx' || ext === 'obj' || ext === 'glb' || ext === 'gltf') {
          modelFiles.push({ file, fileType: ext });
        
        } else if (ext === 'mtl') {
          modelFiles.push({ file, fileType: 'mtl' });
        }
      });

      const textureBlob = textureFile ? await textureFile.async("blob") : null;

      for (const { file, fileType } of modelFiles) {
        await loadModel(file, fileType, textureBlob);
      }
    };

    fetchAndUnzip(zipUrl);

    return () => {
      mountRef.current.innerHTML = '';
    };
  }, [zipUrl]);

  return <div ref={mountRef} style={{ width: 800, height: 600 }} />;
};

export default ModelViewer;

The following is the parsing of files in various formats

switch (fileType) {
        case 'fbx':
          loader = new FBXLoader();
          break;
        case 'obj':
          const mtlFileUrl = getMtlFileUrl(fileUrl);
          const mtlBlob = await fetchMtlBlob(mtlFileUrl);
          const mtlUrl = URL.createObjectURL(mtlBlob);

          const mtlLoader = new MTLLoader();
          mtlLoader.load(mtlUrl, (materials) => {
            materials.preload();
            const objLoader = new OBJLoader();
            objLoader.setMaterials(materials);
            objLoader.load(fileUrl, (object) => {
              applyTexture(object, textureBlob);
              // scene.add(object);
              sizeAndAddModel(object, scene);
              animate(object);
            });
          });
          return;
        case 'gltf':
        case 'glb':
          loader = new GLTFLoader();
          break;
        default:
          console.error(`Unsupported file type: ${fileType}`);
          return;
      }

When a 3D model contains files in three formats: mtl, obj, and png, the texture file is loaded correctly, but the display color is incorrect.