在引入obj文件前确保自己已经完成three.js的初始化(初始化scene,camera,renderer)
接着将所需要展示的obj文件放在项目中
根据官方文档中的描述
const loader = new OBJLoader();
loader.load(
'./obj/file.obj',
function(object){
scene.add(object);
},
//显示模型加载进度
function(xhr){
console.log((xhr.loaded / xhr.total*100)+'%loaded');
},
function(error){
console.log('happend');
}
)
官方文档的前提是他已经正确引入了所有依赖,因此我们这里引入依赖
<script src="./node_modules/three/build/three.js"></script>
<script type="module">
import {OBJLoader} from "./node_modules/three/examples/jsm/loaders/OBJLoader.js"
....
</script>
引入依赖后运行可能会有报错,以下是我遇到的报错问题:
1、
Uncaught SyntaxError: ambiguous indirect export: default
//语法问题,es6的import导出要使用 {}进行包含
import {OBJLoader} from "./node_modules/three/examples/jsm/loaders/OBJLoader.js"
2、
Uncaught SyntaxError: import declarations may only appear at top level of a module
静态的 import
语句用于导入由另一个模块导出的绑定。导入的模块时刻执行在严格模式下。在浏览器中/html文件中,import语句 只能在type=“module”的script标签中使用,因此要在script标签中添加type
<script type="module">
....
</script>
动态import不依赖type=“module” 的script标签
3、
Uncaught TypeError: 解析模块说明符“three”时出错。相对模块说明符必须以“./”、 “../”或 “/”开头
正常引入时出现错误,发现是three.js用到的OBJLoader.js文件中的import问题,如下,我这里直接修改了官方的源码引用部分
import {
EventDispatcher,
MOUSE,
Quaternion,
Spherical,
TOUCH,
Vector2,
Vector3
} from 'three';
//这里three有问题,更改成three.module.js的路径
from '/node_modules/three/build/three.module.js'
4、
已拦截跨源请求:同源策略禁止读取位于 file:///D:/%E9%A1%B9%E7%9B%AE/three/node_modules/three/examples/jsm/loaders/OBJLoader.js 的远程资源。
当在vscode中不经意右键使用 open in default brower 时,vscode将在浏览器中使用文件协议直接打开我们的html文件,可是cors不支持此协议,因此报错。
跨源请求只支持: http, data, chrome, chrome-extension, https.
在vscode中安装插件后使用右键 open with live server即可
5、
THREE.OrbitControls is not a constructor
three.js更新飞快,官方文档中的代码有时候跟不上,这里错误使用了THREE.OrbitControls,应该改为OrbitControls
const controls = new THREE.OrbitControls(camera,renderer.domElement);
//同理还有
const loader = new THREE.OBJLoader();
--去除THREE即可
const controls = new OrbitControls(camera,renderer.domElement);
const loader = new OBJLoader();
完整代码
<!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>Document</title>
<style>
body {
margin: 0;
}
</style>
</head>
<body>
<script src="./node_modules/three/build/three.js"></script>
<script type="module">
import {OBJLoader} from "./node_modules/three/examples/jsm/loaders/OBJLoader.js"
import {OrbitControls} from "./node_modules/three/examples/jsm/controls/OrbitControls.js";
import {MTLLoader} from "./node_modules/three/examples/jsm/loaders/MTLLoader.js"
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
//domElement canvas对象
document.body.appendChild( renderer.domElement );
const loader = new OBJLoader();
const mtlLoader = new MTLLoader();
mtlLoader.load('./obj/test1.mtl',(mtl)=>{
mtl.preload();
loader.setMaterials(mtl);
loader.load('./obj/textured_output.obj', (root) => {
scene.add(root);
});
})
camera.position.z = 5;//因此移动相机
const point = new THREE.PointLight(0xffffff);
point.position.set(400,400,400);
scene.add(point)
const ambient = new THREE.AmbientLight(0x444444);
scene.add(ambient)
renderer.setClearColor(0xb9d3ff,1);
function animate(){
requestAnimationFrame(animate); //向浏览器发起一个执行某函数的请求, 什么时候会执行由浏览器决定,一般默认保持60FPS的频率
renderer.render(scene,camera); //每次渲染出一幅图像
}
animate();
const controls = new OrbitControls(camera,renderer.domElement);
// controls.addEventListener('change',render); //当使用requestAnimationFrame时,没必要在通过controls.addEventListener('change', render)监听鼠标事件调用渲染函数
</script>
</body>
</html>