使用Three.js与@react-three/fiber渲染3D物体时出现黑屏及GLTF缓冲区加载失败错误求助
我跟着JS Mastery在YouTube上的Three.js作品集教程做,但哪怕直接复制Git上的代码,还是一直黑屏,实在搞不定了😭😭
我已经正确安装了Three.js,执行了npm install three,还试过npm install legacy-peer-deps three。GLTF模型的路径也没问题,文件确实放在public文件夹里了,但就是无法正常渲染。
我的代码如下:
import React, { Suspense, useEffect, useState } from "react"; import { Canvas } from "@react-three/fiber"; import { OrbitControls, Preload, useGLTF } from "@react-three/drei"; import CanvasLoader from "../Loader"; const Computers = ({ isMobile }) => { const computer = useGLTF("./desktop_pc/scene.gltf"); return ( <mesh> <hemisphereLight intensity={0.15} groundColor='black' /> <spotLight position={[-20, 50, 10]} angle={0.12} penumbra={1} intensity={1} castShadow shadow-mapSize={1024} /> <pointLight intensity={1} /> <primitive object={computer.scene} scale={isMobile ? 0.7 : 0.75} position={isMobile ? [0, -3, -2.2] : [0, -3.25, -1.5]} rotation={[-0.01, -0.2, -0.1]} /> </mesh> ); }; const ComputersCanvas = () => { const [isMobile, setIsMobile] = useState(false); useEffect(() => { const mediaQuery = window.matchMedia("(max-width: 500px)"); setIsMobile(mediaQuery.matches); const handleMediaQueryChange = (event) => { setIsMobile(event.matches); }; mediaQuery.addEventListener("change", handleMediaQueryChange); return () => { mediaQuery.removeEventListener("change", handleMediaQueryChange); }; }, []); return ( <Canvas frameloop='demand' shadows dpr={[1, 2]} camera={{ position: [20, 3, 5], fov: 25 }} gl={{ preserveDrawingBuffer: true }} > <Suspense fallback={<CanvasLoader />}> <OrbitControls enableZoom={false} maxPolarAngle={Math.PI / 2} minPolarAngle={Math.PI / 2} /> <Computers isMobile={isMobile} /> </Suspense> <Preload all /> </Canvas> ); }; export default ComputersCanvas;
给你几个排查和解决的方向,你可以逐个试试:
先确认模型是否真的加载成功
给useGLTF加个错误回调,看看控制台有没有加载报错:const computer = useGLTF("./desktop_pc/scene.gltf", (error) => { console.error("模型加载失败啦:", error); });另外注意public下的路径,试试把路径改成
/desktop_pc/scene.gltf(前面加斜杠),有时候相对路径会因为组件所在目录的问题找不到文件。检查相机是否能看到模型
你的相机位置是[20, 3, 5],模型在[0, -3.25, -1.5],距离有点远,而且fov只有25,可能模型完全在相机视野外。可以临时把OrbitControls的enableZoom={false}改成true,手动缩放拖动看看能不能找到模型;或者直接把相机位置改成[5, 3, 5]试试。灯光可能太暗导致看不到模型
当前的半球光强度只有0.15,可能太暗了。可以临时把强度调到1,或者加个方向光:<directionalLight intensity={2} position={[0, 10, 5]} />看看能不能看到模型的轮廓。
调整Preload的位置
你现在把<Preload all />放在了Suspense外面,可能预加载没生效。把它移到Suspense内部试试:<Suspense fallback={<CanvasLoader />}> <OrbitControls ... /> <Computers isMobile={isMobile} /> <Preload all /> </Suspense>检查依赖版本兼容性
有时候三个库(three、@react-three/fiber、@react-three/drei)版本不匹配会出各种奇怪问题。可以先卸载这三个依赖,再重新安装:npm uninstall three @react-three/fiber @react-three/drei npm install three @react-three/fiber @react-three/drei先不用加
legacy-peer-deps,除非安装时确实提示peer依赖冲突再用。确认浏览器WebGL支持
打开浏览器的GPU设置页面(比如Chrome里输入chrome://gpu/),看看WebGL是否启用,有没有硬件加速的问题。有些老设备或者浏览器设置可能会禁用WebGL,导致渲染失败。
备注:内容来源于stack exchange,提问作者ded inside girl

