首页 > 解决方案 > React + three.js:TextureLoader 在尝试加载图像时抛出错误

问题描述

我一直在尝试将 three.js 添加到 React 项目中,并且大部分都成功了。但是,我无法弄清楚为什么我的纹理图像没有加载。我正在运行我自己的本地服务器,添加了一个回调方法以在加载完成时运行,并尝试从多个位置加载我的图像,但到目前为止没有任何效果。

我的图像存储在 中public/animation/js/img/texture1.png,我的动画文件存储在 中public/animation/js/animation.js,这里是我现在正在使用的代码:

const Pilot = function () {
  let faceMaterial;
  const geometry = new THREE.CircleGeometry(10, 128);
  const manager = new THREE.LoadingManager();

  manager.onStart = function (url, itemsLoaded, itemsTotal) {
    console.log('Started loading file: ',
      url,
      '.\nLoaded ',
      itemsLoaded,
      ' of ',
      itemsTotal,
      ' files.');
  };
  manager.onLoad = () => {
    console.log('Loading complete!');
  };

  manager.onProgress = function (url, itemsLoaded, itemsTotal) {
    console.log('Loading file: ',
      url,
      '.\nLoaded ',
      itemsLoaded,
      ' of ',
      itemsTotal,
      ' files.');
  };

  manager.onError = function (url) {
    console.error( 'There was an error loading ', url);
  };

  const textureLoader = new THREE.TextureLoader(manager);

  textureLoader.setCrossOrigin('anonymous');

  textureLoader.load('/img/texture1.png',
    texture => {
      faceMaterial = new THREE.MeshFaceMaterial([
        new THREE.MeshBasicMaterial({map: texture}),
        new THREE.MeshBasicMaterial({map: texture}),
        new THREE.MeshBasicMaterial({map: texture}),
        new THREE.MeshBasicMaterial({map: texture}),
        new THREE.MeshBasicMaterial({map: texture}),
        new THREE.MeshBasicMaterial({map: texture})
      ]);
    },
    undefined,
    err => {
      console.error('An error occured:', err);
    }
  );

  this.mesh = new THREE.Mesh(geometry, faceMaterial);
  this.mesh.name = 'profile';
};

标签: javascriptthree.js3d

解决方案


这可能是由于您的图像路径是绝对的,即:'/img/texture1.png'

您的 Web 服务器从哪个目录运行?如果您的 Web 服务器是从/public目录运行的,那么您可能需要更新传递给您的 textureLoaderload方法的图像路径,如下所示:

textureLoader.load('/animation/js/img/texture1.png',

您还需要确保您的网格使用加载纹理数据的相同材质实例。您可以对代码进行以下调整以确保这一点:

// Declare material instance outside of texture load handler
const faceMaterial = new THREE.MeshFaceMaterial([
        new THREE.MeshBasicMaterial(),
        new THREE.MeshBasicMaterial(),
        new THREE.MeshBasicMaterial(),
        new THREE.MeshBasicMaterial(),
        new THREE.MeshBasicMaterial(),
        new THREE.MeshBasicMaterial()
      ])

  const textureLoader = new THREE.TextureLoader(manager);

  textureLoader.setCrossOrigin('anonymous');

  textureLoader.load('/animation/js/img/texture1.png',
    texture => {
      // When texture loads, apply the texture to the map of each sub 
      // material of faceMaterial instance
      faceMaterial.materials[0].map = texture;
      faceMaterial.materials[1].map = texture;
      faceMaterial.materials[2].map = texture;
      faceMaterial.materials[3].map = texture;
      faceMaterial.materials[4].map = texture;
      faceMaterial.materials[5].map = texture;
    },
    undefined,
    err => {
      console.error('An error occured:', err);
    }
  );

  // Apply the faceMaterial instance declared above, to your mesh
  this.mesh = new THREE.Mesh(geometry, faceMaterial);
  this.mesh.name = 'profile';

推荐阅读