使用Three.js的OBJLoader加载模型无显示,求技术排查帮助
Three.js加载OBJ模型无法渲染问题排查
问题描述
使用Three.js加载OBJ格式的女款托特包模型时,模型无法在屏幕上渲染,但几何立方体可正常显示。
相关代码
index.js
import * as THREE from 'three' import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader' import sacola from './sacola.obj'; const renderer = new THREE.WebGLRenderer(); const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); const controls = new OrbitControls( camera, renderer.domElement ); const loader = new OBJLoader(); const scene = new THREE.Scene(); const axesHelper = new THREE.AxesHelper(5) scene.add(axesHelper) renderer.setSize( window.innerWidth, window.innerHeight ); renderer.setClearColor('#000', 0) camera.position.set(0,0,8); controls.enableDamping = true document.body.appendChild( renderer.domElement ); // const geometry = new THREE.BoxGeometry( 1, 1, 1 ); // const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); // const cube = new THREE.Mesh( geometry, material ); // scene.add( cube ); loader.load(sacola, (model) => { model.position.set(0, 0, -53); scene.add( model ) }, ); function animate() { requestAnimationFrame( animate ); renderer.render( scene, camera ); controls.update(); } animate()
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Apresentação 3D</title> </head> <body> </body> </html>
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin') const path = require('path') module.exports = { mode: 'development', entry: path.resolve(__dirname, 'src/index.js'), output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', assetModuleFilename: 'assets/[hash][ext][query]', }, devServer: { port: 3001, open: true, allowedHosts: 'all' }, resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'] }, module: { rules: [ { test: /\.(png|svg|jpg|jpeg|gif|obj)$/i, type: 'asset/resource' }, { test: /\.obj$/, loader: 'webpack-obj-loader' } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/public/index.html', inject: true }) ], }
项目结构

解决建议
1. 修复Webpack配置冲突
当前Webpack同时用asset/resource和webpack-obj-loader处理.obj文件,这会导致加载逻辑混乱——OBJLoader需要的是模型文件的URL,而webpack-obj-loader会把OBJ内容解析为JS对象,不符合加载要求。修改webpack.config.js的rules,移除webpack-obj-loader相关规则:
module: { rules: [ { test: /\.(png|svg|jpg|jpeg|gif|obj)$/i, type: 'asset/resource' } ] }
2. 调整模型位置与缩放
加载的模型可能尺寸过大或位置偏离视野,当前设置model.position.set(0,0,-53),相机在(0,0,8),距离过远且模型可能尺寸超大。可尝试:
- 先移除位置设置,让模型默认在原点
- 添加缩放调整(按需修改数值):
loader.load(sacola, (model) => { model.scale.set(0.05, 0.05, 0.05); // 根据模型实际尺寸调整 scene.add(model); }); - 自动适配视图(更稳妥):
loader.load(sacola, (model) => { const box = new THREE.Box3().setFromObject(model); const center = box.getCenter(new THREE.Vector3()); const size = box.getSize(new THREE.Vector3()); const maxDim = Math.max(size.x, size.y, size.z); const scale = 5 / maxDim; // 让模型最大维度适配5单位空间 model.scale.multiplyScalar(scale); model.position.sub(center.multiplyScalar(scale)); // 模型中心移至原点 scene.add(model); });
3. 添加场景光源
OBJ模型默认使用MeshPhongMaterial,该材质需要光源才能显示。在场景中添加光源:
// 环境光 const ambientLight = new THREE.AmbientLight(0xffffff, 0.6); scene.add(ambientLight); // 方向光 const directionalLight = new THREE.DirectionalLight(0xffffff, 0.4); directionalLight.position.set(5, 5, 5); scene.add(directionalLight);
4. 添加加载错误回调
排查模型是否加载失败,添加错误处理逻辑:
loader.load(sacola, (model) => { // 成功加载逻辑 }, undefined, (error) => { console.error('模型加载失败:', error); });
内容的提问来源于stack exchange,提问作者Diego
相关产品推荐
相关产品推荐

