安装/引入 three.js
方式一:cdn 引入
<script src="https://cdn.bootcss.com/three.js/r83/three.min.js"></script>
<script>
var scene = new THREE.Scene()
console.log(scene)
</script>
缺点:引入 three.js 的插件比如 OrbitControls 的 cdn(来源:https://www.cdnpkg.com/three-orbitcontrols) 后,会报错 Uncaught ReferenceError: require is not defined at OrbitControls.js:1:48
。
原因是 OrbitControls 的 cdn 中引入了 three,但实际上找不到安装的 three,因为这里 three 是通过 cdn 引入的。
目前还没找到解决办法,如果有小伙伴知道了,请在评论区告诉我~
<script src="https://cdn.bootcss.com/three.js/r83/three.min.js"></script>
<script src="https://unpkg.com/three-orbitcontrols@2.110.3/OrbitControls.js"></script>
<script>
var scene = new THREE.Scene()
console.log(scene)
</script>
方式二:用本地静态服务 Live Server 打开 htm
注意事项:
一定要用服务器打开,推荐使用插件 Live Server
,否则直接把 html 在浏览器打开,会报错,提示跨域:
npm i three
后,新建 index.html
,书写下述代码:
办法1(推荐):type="importmap"配置
<!-- 映射目录,即把 `three/addons/` 映射到 `../projects/node_modules/three/examples/jsm/`,注意一定两个地址的末尾都要加 `/`,否则会报错: `Uncaught TypeError: Failed to resolve module specifier "three/addons/controls/OrbitControls.js". Relative references must start with either "/", "./", or "../".` -->
<script type="importmap">
{
"imports": {
"three": "../projects/node_modules/three/build/three.module.js",
"three/addons/": "../projects/node_modules/three/examples/jsm/"
}
}
</script>
<!-- script 标签中一定要加 `type="module"`,否则报错`Uncaught SyntaxError: Cannot use import statement outside a module` -->
<script type="module">
import * as THREE from 'three';
console.log('scene:', THREE.Scene);
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
console.log(OrbitControls);
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'
console.log(GLTFLoader);
// 注意版本变化:`three ^0.150.1` 最新版本
// 旧版本的 THREE.SceneUtils.createMultiMaterialObject 更改为:
import { createMultiMaterialObject } from 'three/addons/utils/SceneUtils.js'
// 使用时直接用 createMultiMaterialObject
// 旧版本的 `new THREE.AxisHelper` 更改为 `new THREE.AxesHelper`
</script>
办法2:ES6 import方式引入three.module.js
<script type="module">
// 报错:Uncaught TypeError: Failed to resolve module specifier "three". Relative references must start with either "/", "./", or "../".
// import * as THREE from 'three';
// 报错: `GET http://127.0.0.1:5500/three net::ERR_ABORTED 404 (Not Found)`
// import * as THREE from '/three';
// 正确:
import * as THREE from './node_modules/three/build/three.module.js';
var scene = new THREE.Scene()
console.log(scene)
</script>
办法3:script标签方式引入three.js
<script src="./node_modules/three/build/three.js"></script>
<script>
// import * as THREE from './node_modules/three/build/three.module.js';
var scene = new THREE.Scene()
console.log(scene)
</script>
方式三:用 vue/react 技术栈
<!-- threeTest.vue -->
<template>
<div class="3d">3d</div>
</template>
<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
export default {
name: "ThreeDIndex",
created() {
console.log(THREE.Scene);
console.log(OrbitControls);
console.log(GLTFLoader);
},
};
</script>
<style lang="scss" scoped></style>
一个 vue+three.js 的 demo
<template>
<div class="3d"></div>
</template>
<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import Stats from "three/examples/jsm/libs/stats.module";
import { createMultiMaterialObject } from "three/examples/jsm/utils/SceneUtils.js";
import * as dat from "dat-gui";
export default {
name: "ThreeDIndex",
created() {
this.loadThreeD();
},
methods: {
loadThreeD() {
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
50,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.set(5, 10, 10);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
/* 1. 使用 dat.GUI 插件 */
// 1.1 dat.GUI 定义对象,设置需要修改的数据
var controls = {
positionX: 0,
positionY: 0,
positionZ: 0,
};
/* 3. 使用 OrbitControls 插件 */
// 3.1 实例化相机插件对象
var control = new OrbitControls(camera, renderer.domElement);
var geometry = new THREE.BoxGeometry(4, 4, 4);
var materialBasic = new THREE.MeshBasicMaterial({
color: 0xffffff,
wireframe: true,
});
var materialNormal = new THREE.MeshNormalMaterial();
var cube = createMultiMaterialObject(geometry, [
materialBasic,
materialNormal,
]);
camera.lookAt(cube.position);
scene.add(cube);
var spotlight = new THREE.SpotLight(0xffffff);
spotlight.position.set(0, 20, 20);
spotlight.intensity = 5;
scene.add(spotlight);
var axes = new THREE.AxesHelper(6);
scene.add(axes);
/* 2. 使用 stats.js */
// 2.1 实例化性能监视插件
var stats = new Stats();
// 2.2 把 stats 对象生成的 dom, 添加到页面中
document.body.appendChild(stats.dom);
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
// 2.3 更新性能插件
stats.update();
// 3.2 在每一帧执行update(可以实时更新一下网格的位置,这样效果更好)
cube.position.set(2, 5, -6);
// 更新相机插件
control.update();
renderer.render(scene, camera);
}
animate();
// 1.2 实例化dat.GUI对象
var gui = new dat.GUI();
// 1.3 把需要修改的配置添加dat.GUI对象中
gui.add(controls, "positionX", -10, 10).onChange(updatePosition);
gui.add(controls, "positionY", -10, 10).onChange(updatePosition);
gui.add(controls, "positionZ", -1, 1).onChange(updatePosition);
// 1.4 定义更新模型位置函数
function updatePosition() {
cube.position.set(
controls.positionX,
controls.positionY,
controls.positionZ
);
}
},
},
};
</script>
<style lang="scss" scoped></style>
参考链接
- 网上关于 three.js 的帖子不够精细,推荐一个学习 three.js 的网址:http://webgl3d.cn/pages/cd35b2/
- THREE.js 学习的时候,用的版本一定要注意
本文来自博客园,作者:shayloyuki,转载请注明原文链接:https://www.cnblogs.com/shayloyuki/p/17191489.html
posted on 2023-03-09 14:14 shayloyuki 阅读(3123) 评论(0) 编辑 收藏 举报