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

React Three中同一3D模型加载多张纹理失败的解决方法

React Three Fiber中FBX模型纹理不显示的修复方案

以下是针对你遇到问题的具体修复步骤:

  • 修正材质类型与纹理属性
    meshBasicMaterial是无光照材质,无法解析法线纹理的光照计算,且法线纹理需要赋值给normalMap而非map属性。将材质替换为支持光照的meshStandardMaterial:

    function Character(props) {
        const obj = useFBX('/character.fbx');
        const bodyNormal = useTexture('/textures/body_normal.png')
        const bodyColor = useTexture('/textures/body_base_color.png')
    
        return <mesh>
            <primitive object={obj} />
            <meshStandardMaterial map={bodyColor} attach="material-0" />
            <meshStandardMaterial normalMap={bodyNormal} attach="material-1" />
        </mesh>
    }
    
  • 验证材质索引匹配
    FBX模型导出时的材质顺序可能与预期不符,先打印模型材质信息确认索引:

    useEffect(() => {
      if (obj) console.log('模型材质列表:', obj.material)
    }, [obj])
    

    若索引不匹配,可直接替换整个材质数组:

    <mesh material={[
      new THREE.MeshStandardMaterial({ map: bodyColor }),
      new THREE.MeshStandardMaterial({ normalMap: bodyNormal })
    ]}>
      <primitive object={obj} />
    </mesh>
    
  • 等待纹理加载完成
    纹理未加载完成时渲染会导致显示异常,可通过检查loaded状态等待加载:

    function Character(props) {
        const obj = useFBX('/character.fbx');
        const bodyNormal = useTexture('/textures/body_normal.png')
        const bodyColor = useTexture('/textures/body_base_color.png')
    
        if (!bodyNormal.loaded || !bodyColor.loaded) return null
    
        return <mesh>
            <primitive object={obj} />
            <meshStandardMaterial map={bodyColor} attach="material-0" />
            <meshStandardMaterial normalMap={bodyNormal} attach="material-1" />
        </mesh>
    }
    
  • 处理嵌套子网格材质
    部分FBX模型的材质绑定在子网格上,需遍历模型赋值:

    function Character(props) {
        const obj = useFBX('/character.fbx');
        const bodyNormal = useTexture('/textures/body_normal.png')
        const bodyColor = useTexture('/textures/body_base_color.png')
    
        useEffect(() => {
          if (obj) {
            obj.traverse(child => {
              if (child.isMesh && child.name === 'Body') {
                child.material = new THREE.MeshStandardMaterial({
                  map: bodyColor,
                  normalMap: bodyNormal
                })
              }
            })
          }
        }, [obj, bodyColor, bodyNormal])
    
        return <primitive object={obj} />
    }
    

内容的提问来源于stack exchange,提问作者Andrea D'Attero

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 21:30:50