React+Three.js中GLTF/GLB模型显示异常求助
React + Three.js 模型加载问题:模型极小且放大后变形
我在React环境中使用Three.js开发,通过gltfjsx将GLTF/GLB格式的3D模型转换为JSX组件展示。加载流程看似正常,但页面上看不到模型。排查后发现模型尺寸极小,调整相机放大后完全变形。尝试用Visual Studio插件将GLTF转为JSON格式的GLTF文件,问题依旧。
相关代码
App.js
import { Canvas } from "@react-three/fiber"; import { Model } from "./Model"; import { Suspense } from "react"; function App() { return ( <> <Canvas> <Suspense fallback={<LoadingFallback />}> <Model position={[0, 0, 0]} /> </Suspense> </Canvas> </> ); } function LoadingFallback() { return ( <mesh visible position={[0, 0, 0]}> <sphereGeometry args={[1, 16, 16]} /> <meshStandardMaterial color="red" /> </mesh> ); } export default App;
Model.jsx
import React, { useRef } from "react"; import { useGLTF } from "@react-three/drei"; export function Model(props) { const { nodes, materials } = useGLTF("model.gltf"); return ( <group {...props} dispose={null}> <mesh geometry={nodes.mesh_0.geometry} material={nodes.mesh_0.material} position={[-0.059, 0, 0.056]} rotation={[-Math.PI / 2, 0, 0]} /> <mesh geometry={nodes.mesh_1.geometry} material={nodes.mesh_1.material} position={[-0.059, 0, 0.056]} rotation={[-Math.PI / 2, 0, 0]} /> </group> ); } useGLTF.preload("/model.gltf");
model.gltf
{ "asset": { "generator": "3D Builder", "version": "2.0" }, "scene": 0, "scenes": [ { "nodes": [ 0, 1 ] } ], "nodes": [ { "mesh": 0, "matrix": [ 1, 0, 0, 0, 0, -1.1920928955078125e-7, -0.9999998807907104, 0, 0, 0.9999998807907104, -1.1920928955078125e-7, 0, -0.0589279979467392, 6.676553532258822e-9, 0.056006982922554016, 1 ] }, { "mesh": 1, "matrix": [ 1, 0, 0, 0, 0, -1.1920928955078125e-7, -0.9999998807907104, 0, 0, 0.9999998807907104, -1.1920928955078125e-7, 0, -0.0589279979467392, 6.676553532258822e-9, 0.056006982922554016, 1 ] } ], "meshes": [ { "primitives": [ { "attributes": { "POSITION": 0, "COLOR_0": 1 }, "mode": 4, "indices": 2 } ] }, { "primitives": [ { "attributes": { "POSITION": 3, "COLOR_0": 4 }, "mode": 4, "indices": 5 } ] } ], "accessors": [ { "bufferView": 0, "byteOffset": 0, "count": 86, "componentType": 5126, "type": "VEC3", "min": [ 0.049275994300842285, -1.3066596265629834e-16, 0 ], "max": [ 0.1178559958934784, 0.08991597592830658, 0.018389593809843063 ] }, { "bufferView": 1, "byteOffset": 0, "count": 86, "componentType": 5121, "type": "VEC4", "normalized": true }, { "bufferView": 2, "byteOffset": 0, "count": 504, "componentType": 5125, "type": "SCALAR" }, { "bufferView": 3, "byteOffset": 0, "count": 120, "componentType": 5126, "type": "VEC3", "min": [ 0, -1.3066596265629834e-16, 0 ], "max": [ 0.09220199286937714, 0.11201398074626923, 0.018389593809843063 ] }, { "bufferView": 4, "byteOffset": 0, "count": 120, "componentType": 5121, "type": "VEC4", "normalized": true }, { "bufferView": 5, "byteOffset": 0, "count": 708, "componentType": 5125, "type": "SCALAR" } ], "bufferViews": [ { "buffer": 0, "byteOffset": 0, "byteLength": 1032, "byteStride": 12, "target": 34962 }, { "buffer": 0, "byteOffset": 1032, "byteLength": 344, "byteStride": 4, "target": 34962 }, { "buffer": 0, "byteOffset": 1376, "byteLength": 2016, "target": 34963 }, { "buffer": 0, "byteOffset": 3392, "byteLength": 1440, "byteStride": 12, "target": 34962 }, { "buffer": 0, "byteOffset": 4832, "byteLength": 480, "byteStride": 4, "target": 34962 }, { "buffer": 0, "byteOffset": 5312, "byteLength": 2832, "target": 34963 } ], "buffers": [ { "uri": "model_data.bin", "byteLength": 8144 } ] }
问题分析与解决办法
1. 修复模型尺寸问题
从GLTF的accessor数据可以看到,模型顶点坐标的最大范围仅0.1左右,说明模型本身单位尺寸极小。直接放大相机视角会导致透视变形,正确做法是缩放模型本身:
修改Model.jsx的外层group,添加scale属性:
<group {...props} dispose={null} scale={[10, 10, 10]}>
可根据实际效果调整缩放倍数。
2. 添加交互控件调整视角
默认Canvas的相机位置可能未对准模型,建议添加OrbitControls方便手动调整视角:
先确保安装了@react-three/drei,然后在App.js中修改:
import { Canvas } from "@react-three/fiber"; import { Model } from "./Model"; import { Suspense, OrbitControls } from "@react-three/drei"; import { Suspense as ReactSuspense } from "react"; function App() { return ( <> <Canvas> <ReactSuspense fallback={<LoadingFallback />}> <Model position={[0, 0, 0]} /> </ReactSuspense> <OrbitControls enableZoom={true} /> </Canvas> </> ); }
3. 修复代码遗漏问题
原App.js中使用了Suspense但未从react导入,需补上:
import { Suspense } from "react";
4. 优化模型导出流程
3D Builder导出的GLTF可能存在坐标或变换异常,建议用Blender重新导出:
- 将模型导入Blender
- 选中模型按
Ctrl+A,依次应用缩放、旋转、位置变换 - 导出为GLTF时,勾选"应用变换"选项
内容的提问来源于stack exchange,提问作者Dimitris S
相关产品推荐
相关产品推荐

