You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OBJ模型滚动纹理材质失效问题求助:如何修复?

问题解决:OBJ模型应用滚动纹理材质失效

问题根源

OBJ模型加载后通常是一个包含多个子网格(Mesh)的Group对象,你当前代码直接获取顶层mesh对象并尝试读取其material属性,但Group本身没有material,导致后续纹理替换逻辑无法生效,模型显示默认白色;而基础立方体是单个Mesh,所以代码能正常运行。

解决方案

1. 遍历模型所有子网格,批量处理材质

修改model-loaded事件中的逻辑,遍历模型的所有子对象,筛选出Mesh类型的实体,收集它们的材质(支持单个材质或材质数组),再统一更新纹理。

2. 确保纹理加载完成后再启动动画

原代码中TextureLoader.load是异步操作,可能模型加载完成时纹理还未加载完毕,导致初始状态为白色,可通过Promise.all等待所有纹理加载完成后再启动动画。

修改后的完整代码

<script>
  function startPlaying(event) {
    // document.getElementById("scene").style.display = "block";
    // document.getElementById("videoTex").play();
    // event.target.style.display="none";
  }

  AFRAME.registerComponent("slideshow", {
    init: function () {
      let loader = new THREE.TextureLoader();
      let anim1_frames = 20; // 总帧数
      // 用Promise封装纹理加载,等待所有纹理加载完成
      const loadTexture = (url) => {
        return new Promise((resolve, reject) => {
          loader.load(url, resolve, undefined, reject);
        });
      };

      const texturePromises = [];
      for (var i = 0; i < anim1_frames; i++) {
        texturePromises.push(loadTexture(`https://urginsan.github.io/webTesting/sequence1/TextureAtlas_${i}.png`));
      }

      Promise.all(texturePromises).then((pngArray) => {
        this.pngArray = pngArray;
        // 处理模型加载逻辑
        const handleModelLoaded = () => {
          let model = this.el.getObject3D('mesh');
          this.materials = [];
          // 遍历所有子网格,收集材质
          model.traverse(obj => {
            if (obj.isMesh) {
              if (Array.isArray(obj.material)) {
                this.materials.push(...obj.material);
              } else {
                this.materials.push(obj.material);
              }
            }
          });

          if (!this.materials || this.materials.length === 0) return;

          let i = 0;
          this.id = setInterval(() => {
            if (i >= this.pngArray.length) i = 0;
            const currentTexture = this.pngArray[i++];
            // 更新所有材质的纹理
            this.materials.forEach(material => {
              material.map = currentTexture;
              material.needsUpdate = true;
            });
          }, 1000 / 25); // 25fps
        };

        // 检查模型是否已提前加载完成
        if (this.el.getObject3D('mesh')) {
          handleModelLoaded();
        } else {
          this.el.addEventListener('model-loaded', handleModelLoaded);
        }
      }).catch(err => {
        console.error("纹理加载失败:", err);
      });
    },
    remove: function () {
      clearInterval(this.id);
      // 释放纹理内存
      if (this.pngArray) {
        this.pngArray.forEach(texture => texture.dispose());
      }
    }
  })
</script>

额外注意事项

  • 如果OBJ模型的子网格使用了不支持map属性的材质(如MeshDepthMaterial),需要先替换为MeshStandardMaterial或MeshBasicMaterial再设置纹理。
  • 可以在traverse逻辑中添加日志,确认是否正确找到所有子网格:console.log("找到子网格:", obj)

内容的提问来源于stack exchange,提问作者URGINSAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 17:24:58