使用@react-three/drei的useGLTF时Three.js场景崩溃如何解决?
解决方案
核心问题定位
- Suspense 位置错误:
useGLTF是异步加载钩子,你将 Suspense 放在 Skull 组件内部包裹返回值时,钩子执行阶段还未被 Suspense 捕获,会直接读取未加载完成的nodes对象导致崩溃 - 静态资源路径错误:Next.js 项目中直接引用根路径的静态资源,需要将
skull.gltf放在项目根目录的public文件夹下 - meshopt 解码兼容问题:你使用的 glTF 经过 meshopt 压缩,当前版本依赖的解码器默认开启实验性 SIMD 支持,存在兼容问题导致 WebGL 上下文丢失
- 依赖版本冲突:
@react-three/drei@7.5.0与three@0.132.2存在已知的 meshopt 解码适配 bug
修复步骤
1. 调整代码结构与Suspense位置
修正后的完整代码如下:
import React, { Suspense } from 'react' import { Canvas } from '@react-three/fiber' import Layout from '../components/layout' import { Sky, OrbitControls, useGLTF } from '@react-three/drei' // 预加载模型并关闭meshopt的SIMD支持 useGLTF.preload('skull.gltf', { meshoptDecoderOptions: { simd: false } }) const Skull = () => { const { nodes } = useGLTF('skull.gltf') return <mesh geometry={nodes.mesh_0.geometry} /> } export default function Home() { return ( <Layout> <Canvas gl={{ preserveDrawingBuffer: true, powerPreference: 'high-performance' }}> <Sky sunPosition={[0, 1, 0]} /> {/* Suspense包裹异步加载的组件 */} <Suspense fallback={null}> <Skull /> </Suspense> <OrbitControls /> </Canvas> </Layout> ) }
2. 修复依赖版本兼容问题
修改 package.json 中的依赖版本,降级存在冲突的包:
{ "dependencies": { "@react-three/drei": "7.4.0", "three-stdlib": "2.3.0" } }
修改完成后删除 node_modules 文件夹、yarn.lock 或 package-lock.json 文件,重新执行依赖安装命令即可。
3. 可选模型转码方案
如果上述修改后仍存在解码警告,可以本地转码模型,关闭 meshopt 压缩后再引入项目使用。
内容的提问来源于stack exchange,提问作者Robert Sims
相关产品推荐
相关产品推荐

