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

在React Native中用Three.js加载obj&mtl文件时遇document未定义问题

解决React Native中MTLLoader加载时"Can't find variable: document"的问题

这个坑我之前在React Native结合WebGL加载3D模型时踩过,核心原因很直白:Three.js官方的MTLLoader依赖的TextureLoader是为浏览器环境设计的,它内部会调用浏览器的document对象创建图片元素,但React Native里根本没有这个浏览器API,直接用自然会报错。下面给你几个实用的解决办法:

方法1:自定义适配React Native的TextureLoader

我们可以自己实现一个不依赖document的纹理加载器,用React Native原生的Image模块来加载图片,替换掉MTLLoader默认的TextureLoader。

步骤:

  1. 导入React Native的Image组件,创建自定义加载器类:
import { Image } from 'react-native';
import * as THREE from 'three';

class RNTextureLoader extends THREE.Loader {
  load(url, onLoad, onProgress, onError) {
    // 处理RN的资源路径:本地require的资源需要转成可访问的uri
    const resolvedUri = typeof url === 'number' ? Image.resolveAssetSource(url).uri : url;

    // 用RN的Image获取图片信息并加载
    Image.getSize(resolvedUri, (width, height) => {
      const image = new Image();
      image.src = resolvedUri;
      
      image.onload = () => {
        const texture = new THREE.Texture(image);
        texture.needsUpdate = true; // 标记纹理需要更新
        onLoad(texture);
      };
      
      image.onerror = (err) => {
        onError?.(err);
      };
    }, (err) => {
      onError?.(err);
    });
  }
}
  1. 在使用MTLLoader时,替换默认的纹理加载器:
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader';
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';

const mtlLoader = new MTLLoader();
// 用自定义的RNTextureLoader替换默认加载器
mtlLoader.setTextureLoader(new RNTextureLoader());

// 加载MTL文件并后续加载OBJ模型
mtlLoader.load(
  './assets/model.mtl',
  (materials) => {
    materials.preload();
    const objLoader = new OBJLoader();
    objLoader.setMaterials(materials);
    objLoader.load('./assets/model.obj', (object) => {
      // 将模型添加到WebGL场景中
      scene.add(object);
    });
  },
  (xhr) => console.log(`加载进度: ${(xhr.loaded / xhr.total) * 100}%`),
  (err) => console.error('MTL加载失败:', err)
);

方法2:使用适配好的第三方库(更省心)

如果不想自己写加载器,可以直接用react-native-three这个库,它是专门为React Native封装的Three.js工具集,里面的所有加载器都已经适配了RN环境,不会出现浏览器API依赖的问题。

步骤:

  1. 安装依赖(注意和你的RN版本兼容):
npm install react-native-three
# 或者用yarn
yarn add react-native-three
  1. 直接导入使用封装好的加载器:
import { MTLLoader, OBJLoader } from 'react-native-three';

// 使用方式和官方Three.js几乎一致,无需额外适配
const mtlLoader = new MTLLoader();
mtlLoader.load('./assets/model.mtl', (materials) => {
  materials.preload();
  const objLoader = new OBJLoader();
  objLoader.setMaterials(materials);
  objLoader.load('./assets/model.obj', (object) => {
    scene.add(object);
  });
});

额外注意事项

  • 确保模型和纹理文件放在RN项目的可访问路径下(比如assets文件夹),并且在metro.config.js中配置了资源解析规则,避免加载失败。
  • 本地资源尽量用require('./assets/texture.png')的方式引入,或者确保路径是RN能识别的绝对URI。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:26:56