如何引入threejs
对于很多刚刚上手threejs的朋友,可能第一步引入threejs就出问题了,
明明已经导入了,就是这样问题那样问题,所以我们首先来看一下threejs的引入问题。
3种方式:
- npm安装依赖,使用webpack之类的打包工具处理
- script直接导入
- script module方式import
npm方式
# 安装项目依赖
npm install three
// import引入three.js
import * as THREE from 'three';
这种方式通常需要结合其他打包工具一起使用,否则还是需要像第3种方式一样。
script方式
先下载threejs相关包
然后:
<script src='js/three.min.js'></script>
这种方式最方便,但是不推荐,因为r160+就不支持了
但可以使用下面的方式
script module方式
<script type="importmap">
{
"imports": {
"three": "./js/three.module.js",
"three/addons/": "./js/jsm/"
}
}
</script>
<script type="module">
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
const scene = new THREE.Scene();
</script>
2点注意:
- type的方式必须是module,才能使用import
- importmap表示映射关系,以免每次写完整的路径,例如上面就是将./js/three.module.js路径映射为three,import就可以直接from three
这种方式也可以使用npm three来安装依赖:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>npm threejs</title>
</head>
<body>
</body>
</html>
<script type="importmap">
{
"imports": {
"three": "./node_modules/three/build/three.module.js",
"three/addons/": "./node_modules/three/examples/jsm/"
}
}
</script>
<script type="module">
import * as THREE from 'three';
//创建场景
const scene = new THREE.Scene();
//创建透视投影相机,视角45度,画幅比例 宽比高,近平面距离0.1,远平面1000
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
//创建渲染器
const renderer = new THREE.WebGLRenderer();
//渲染器canvas宽高设为与窗口一致
renderer.setSize(window.innerWidth, window.innerHeight);
//将渲染器对应的dom元素添加到body中
document.body.appendChild(renderer.domElement);
//定义一个几何体
const geometry = new THREE.SphereGeometry(3, 30, 30);
//定义一种材质,显示为线框
const material = new THREE.MeshBasicMaterial({
color: 0xB3DD,
wireframe: true
});
//网孔(Mesh)是用来承载几何模型的一个对象,可以把材料应用到它上面
const ball = new THREE.Mesh(geometry, material);
//把几何模型添加到场景中,对象被添加到原点(0,0,0)坐标。
scene.add(ball);
//移动相机位置
camera.position.z = 8;
function render() {
//渲染循环,以每秒60次的频率来绘制场景
requestAnimationFrame(render);
//设置球体绕y轴旋转
ball.rotation.y += 0.005;
renderer.render(scene, camera);
}
render();
</script>
基本流程与坐标
- threejs首先需要一个场景Scene作为容器用来放物体
- 需要一些物体放入场景中
- 需要一个相机Camera来观察场景
- 需要一个Renderer来渲染相机看到的指定场景,如WebGLRenderer渲染完成就可以获取到一个dom元素
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>npm threejs</title>
</head>
<body>
</body>
</html>
<script type="importmap">
{
"imports": {
"three": "./node_modules/three/build/three.module.js",
"three/addons/": "./node_modules/three/examples/jsm/"
}
}
</script>
<script type="module">
import * as THREE from 'three';
// 创建渲染器,画布
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.pixelRatio = window.devicePixelRatio;
renderer.setSize(window.innerWidth, window.innerHeight);
// 画布添加到body中
document.body.append(renderer.domElement);
// 也可以添加到指定的元素中
// document.getElementById('threeBox').appendChild(renderer.domElement);
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
// 创建物体
const axis = new THREE.AxesHelper(5);
// 设置x、y、z坐标颜色
axis.setColors("pink",0xffff00,"blue");
scene.add(axis);
// 设置坐标位置,否则相机和物体默认都在坐标原点啥都看不见
camera.position.set(5, 5, 10);
camera.lookAt(0, 0, 0);
// 渲染
renderer.render(scene, camera);
</script>
threejs是右手坐标系,X轴向右、Y轴向上,Z轴垂直屏幕向外。
我们可以看到对应的轴和我们设置的颜色一致。
摄像机
相机是一个非常重要的概念,我们最终看到的都是摄像机看到的场景中物体。
相机在所有3D中基本都一样,最常用的就是透视摄像机PerspectiveCamera:
- fov:摄像机视野角度
- aspect:摄像机裁面长宽比
- near:摄像机原点到近裁面距离
- far: 摄像机原点到远裁面距离
透视相机就是和我们生活中的相机一样,和眼睛看到的也差不多,近大远小,距离相机近的物体显示的大,距离相机远的物体显示的小。
如果不知道怎么设置,可以直接使用下面的设置:
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
Geometry(几何体)和Material(材质)
// 添加立方体
const geometry = new THREE.BoxGeometry(2, 2, 2);
const material = new THREE.MeshBasicMaterial({ color: 0xffecda });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>npm threejs</title>
</head>
<body>
</body>
</html>
<script type="importmap">
{
"imports": {
"three": "./node_modules/three/build/three.module.js",
"three/addons/": "./node_modules/three/examples/jsm/"
}
}
</script>
<script type="module">
import * as THREE from 'three';
// 创建渲染器,画布
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.pixelRatio = window.devicePixelRatio;
renderer.setSize(window.innerWidth, window.innerHeight);
// 画布添加到body中
document.body.append(renderer.domElement);
// 也可以添加到指定的元素中
// document.getElementById('threeBox').appendChild(renderer.domElement);
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
// 创建物体
const axis = new THREE.AxesHelper(5);
// 设置x、y、z坐标颜色
axis.setColors("pink",0xffff00,"blue");
scene.add(axis);
// 设置坐标位置,否则相机和物体默认都在坐标原点啥都看不见
camera.position.set(5, 5, 10);
camera.lookAt(0, 0, 0);
// 添加立方体
const geometry = new THREE.BoxGeometry(2, 2, 2);
const material = new THREE.MeshBasicMaterial({ color: 0xffecda });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// 渲染
renderer.render(scene, camera);
</script>
光源
three.js中有三种重要的光源:
- 环境光(Ambient Light):环境光是一种均匀的光照,它会均匀地照亮场景中的所有物体,不考虑光照源的位置和方向
- 方向光(Directional Light):方向光是一种平行光源,它具有确定的方向和强度,类似于太阳光
- 点光源(Point Light):点光源是一种位于特定位置的光源,它向所有方向发射光线,类似于灯泡
MeshBasicMaterial不受光源影响,可以使用MeshStandardMaterial
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>npm threejs</title>
</head>
<body>
</body>
</html>
<script type="importmap">
{
"imports": {
"three": "./node_modules/three/build/three.module.js",
"three/addons/": "./node_modules/three/examples/jsm/"
}
}
</script>
<script type="module">
import * as THREE from 'three';
// 创建渲染器,画布
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.pixelRatio = window.devicePixelRatio;
renderer.setSize(window.innerWidth, window.innerHeight);
// 画布添加到body中
document.body.append(renderer.domElement);
// 也可以添加到指定的元素中
// document.getElementById('threeBox').appendChild(renderer.domElement);
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
// 创建物体
const axis = new THREE.AxesHelper(5);
// 设置x、y、z坐标颜色
axis.setColors("pink",0xffff00,"blue");
scene.add(axis);
// 设置坐标位置,否则相机和物体默认都在坐标原点啥都看不见
camera.position.set(5, 5, 10);
camera.lookAt(0, 0, 0);
// 添加立方体
const geometry = new THREE.BoxGeometry(2, 2, 2);
const material = new THREE.MeshStandardMaterial({ color: 0xffecda });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(10, 0, 10);
scene.add(directionalLight);
// 渲染
renderer.render(scene, camera);
</script>