React Native中useTexture加载纹理失败,报unsupported URL错误求助
React Native中@react-three/drei useTexture加载本地纹理失败的解决方案
问题根源
在React Native环境中,@react-three/drei的useTexture无法直接识别相对路径字符串(如'textures/earth_textures/earth.jpeg')。这是因为React Native的资源打包机制要求必须通过require()或静态import引入本地资源,否则会触发"unsupported URL"错误。
具体解决方法
方法1:使用require()引入资源路径
修改Earth组件的纹理加载代码,通过require()获取资源的正确URI:
import { useRef } from "react"; import { useFrame } from "@react-three/fiber"; import { useTexture } from "@react-three/drei"; function Earth(props) { // 注意:路径需与项目实际文件结构匹配,例如textures在项目根目录下则用../textures/... const dayTexture = useTexture(require('../textures/earth_textures/earth.jpeg')); const mesh = useRef(); useFrame(() => { mesh.current?.rotation.x += 0.01; }); return ( <mesh {...props} ref={mesh} scale={[1,1,1]}> <sphereGeometry attach="geometry"/> <meshStandardMaterial map={dayTexture} attach="material" /> </mesh> ) }
方法2:静态import资源
先通过import引入图片资源,再传递给useTexture:
import { useRef } from "react"; import { useFrame } from "@react-three/fiber"; import { useTexture } from "@react-three/drei"; // 导入本地纹理资源 import EarthTexture from '../textures/earth_textures/earth.jpeg'; function Earth(props) { const dayTexture = useTexture(EarthTexture); const mesh = useRef(); useFrame(() => { mesh.current?.rotation.x += 0.01; }); return ( <mesh {...props} ref={mesh} scale={[1,1,1]}> <sphereGeometry attach="geometry"/> <meshStandardMaterial map={dayTexture} attach="material" /> </mesh> ) }
调整Suspense的位置
原代码中Suspense包裹的是meshStandardMaterial,但useTexture是在Earth组件内部执行的异步操作,需将Suspense移到Earth组件的外层:
import { Suspense } from "react"; import { StyleSheet, View } from "react-native"; import { Canvas } from "@react-three/fiber"; import Earth from './Earth'; // 假设Earth组件在单独文件中 export default function App() { return ( <View style={styles.container}> <Canvas> <directionalLight position={[0.5, 0.5, 0.5]} intensity={4} /> <Suspense fallback={null}> <Earth position={[0, 0, 0]} /> </Suspense> </Canvas> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "black", }, });
额外检查项
- 确保
metro.config.js中配置了支持的图片扩展名(默认已包含常见格式,若自定义过需确认添加jpeg/jpg):
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); const config = {}; module.exports = mergeConfig(getDefaultConfig(__dirname), config);
- 检查文件路径拼写,iOS环境下路径大小写敏感,需严格匹配实际文件名
内容的提问来源于stack exchange,提问作者willyium04
相关产品推荐
相关产品推荐

