Three 基础环境
THREE三要素 (scene场景、camera摄像机、renderer渲染器)
1、首先我们需要引入three.js包,引入 three.js 对象(命名导出->默认导入)
import * as THREE from 'three';
2、创建scene场景
const scene = new THREE.Scene();
3、创建摄像机(人眼)
// 参数1:角度(摄像机查看范围)
// 参数2:宽高比(和画布比例一致,不然会被拉伸/压缩物体)
// 参数3:近截面距离
// 参数4:远截面距离(会影响空间被划分份数)
const camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
4、创建渲染器(绘制)
const renderer = new THREE.WebGLRenderer();
5、设置画布大小(会生成 canvas 标签)
renderer.setSize(window.innerWidth,window.innerHeight)
6、把画布标签添加到页面显示
document.body.appendChild(renderer.domElement)
7、渲染 - 传入场景和摄像机
renderer.render(scene,camera)
设置完成画布一篇漆黑,因为是我们画布里面什么都没有,这就需要给画布中添加我们的物体了。
绘制实体(立方体 )
1、创建正方体图形,宽度高度深度都为 2
const geometry = new THREE.BoxGeometry(2,2,2);
2、创建材质,颜色为绿色(与 css 颜色使用相同),颜色支持英文字符串('red'),16进制颜色(0xffffff,#ed1c24), rgba 颜色字符串('rgba(123, 123, 123, 1)',以及 hsl 颜色 ('hsl(255,90%,50%)')
const material = new THREE.MeshBasicMaterial({
color: 0xed1c24
});
3、创建网格对象,传入几何图形和材质,得到正方体对象
const mesh = new THREE.Mesh(geometry,material);
4、添加到场景中(默认正方体中心和画布中心原点重合)
scene.add(mesh);
// 问题:发现看不见,是因为摄像机默认镜头也在原点位置,贴上了
// 解决:将摄像机往后移动 10 单位
// 提问:摄像机拉的越远,图形会不会越小?会!因为近大远小-摄像机模拟了现实中的现象
// 提问:扩大视角,图形会不会越小?会!因为角度大了,焦距小了,入射光角度小了,所以物体成像小
camera.position.y = 10;
camera.position.x = 10;
camera.position.z = 20;
5、最后渲染
renderer.render(scene, camera);
轨道控制器 (controls)
1、引入控件
// 引入相机控件 路径根据自己的文件路径
import { OrbitControls } from '../../js/jsm/controls/OrbitControls.js';
2、创建轨道控制器对象
// 参数1:摄像机,参数2:用于事件监听的 DOM 元素(canvas 画布标签)- 监听鼠标拖拽
const controls = new OrbitControls(camera,renderer.domElement);
3、在渲染循环中更新场景渲染
function render(){
renderer.render(scene, camera);
// 当代码修改了摄像机参数,需要更新轨道控制
// controls.update();
// 注意:在渲染循环更新轨道控制器,会影响摄像机的 lookAt 方法
// 解决:可以用 controls.target 来设置影响摄像机的 lookAt
// 选择:当依赖轨道控制器实现阻尼等效果,需要 update(), 如果不需要阻尼等效果,则不用在这里调用 update()
// 根据当前计算机浏览器刷新帧率(一般 60 次/秒),不断递归调用此函数渲染最新的画面状态
// 好处:当前页面切换到后台,暂停递归
requestAnimationFrame(render)
}
render()
controls 属性介绍
1、相机自动围绕目标水平旋转(顺时针) autoRotate
2、相机惯性阻尼感觉 enableDamping
3、相机垂直旋转的角度上限 (旋转范围角度是 0 到 π) maxPolarAngle
4、相机垂直旋转的角度下限 minPolarAngle
5、相机向外能移动多少(默认无限大) maxDistance
6、相机向内能移动多少(默认值为 0)相机贴在图上 minDistance
7、禁止右键拖拽 enablePan
8、禁止缩放 enableZoom
9、禁止旋转 enableRotate
10、键盘控制相机平移 keys
// 相机自动围绕目标水平旋转(顺时针)
controls.autoRotate = true;
// 相机惯性阻尼感觉
controls.enableDamping = true;
// 相机垂直旋转的角度上限 (旋转范围角度是 0 到 π)
controls.maxPolarAngle = Math.PI / 2;
// 相机垂直旋转的角度下限
controls.minPolarAngle = Math.PI / 2;
// 相机向外能移动多少(默认无限大)
controls.maxDistance = 50;
// 相机向内能移动多少(默认值为 0)相机贴在图上
controls.minDistance = 10;
// 禁止右键拖拽
controls.enablePan = false;
// 禁止缩放
controls.enableZoom = false;
// 禁止旋转
controls.enableRotate = false;
// 键盘控制相机平移(属性和值都是默认的,4 个方向键)
controls.keys = {
LEFT: 'ArrowLeft', //left arrow
UP: 'ArrowUp', // up arrow
RIGHT: 'ArrowRight', // right arrow
BOTTOM: 'ArrowDown' // down arrow
};
// 为指定的 DOM 元素添加按键监听,推荐监听 window 窗口
controls.listenToKeyEvents(window)
坐标轴 (AxesHelper)
1、创建坐标轴辅助对象
// 参数:刻度线长度
const axesHelper = new THREE.AxesHelper(10)
2、添加到场景中
scene.add(axesHelper)
物体变换 (Vector3 三维向量对象)
1、对物体进行变换,“位移”,“旋转”,“缩放” , 位移 position 属性(Vector3 三维向量对象)
// mesh.position.x = 5;
mesh.position.set(5,5,5);
2、旋转 rotation 属性(Euler 欧拉角弧度制角度对象),x,z,y 从轴的正方向看去,值增加时,是逆时针绕轴旋转
mesh.rotation.x = Math.PI / 3
(1)可以配合渲染循环,不断旋转
function render() {
renderer.render(scene, camera)
// 可以配合渲染循环,不断旋转
cube.rotation.x += 0.01
cube.rotation.y += 0.01
requestAnimationFrame(render)
}
render()
(2)配合键盘使用
window.addEventListener('keydown', e => {
switch (e.key) {
case 'd':
cube.position.x += 0.01
break;
case 'w':
cube.position.y += 0.01
break;
case 's':
cube.position.y -= 0.01
break;
case 'a':
cube.position.x -= 0.01
break;
}
})
3、缩放 scale 属性(Vector3 三维向量对象,中心原点不动,向 2 边拉伸/缩小)
mesh.scale.z = 2
最后贴上完整代码如下
import * as THREE from 'three'
import { OrbitControls } from '../../js/jsm/controls/OrbitControls.js'; // 引入相机控件
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);
const renderer = new THREE.WebGL1Renderer();
renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement);
const geometry = new THREE.BoxGeometry(2,2,2);
const material = new THREE.MeshBasicMaterial({
color: 0xff00ff,
antialias: true // 3. 发现有锯齿,给 WebGLRenderer 构造函数中传入配置对象: { antialias: true }
})
const mesh = new THREE.Mesh(geometry,material);
scene.add(mesh);
camera.position.z = 10;
camera.position.x = 10;
camera.position.y = 20;
const controls = new OrbitControls(camera, renderer.domElement)
const axesHelper = new THREE.AxesHelper(10)
// 2. 添加到场景中
scene.add(axesHelper)
// 目标:对物体进行变换,“位移”,“旋转”,“缩放”
// 1. 位移 position 属性(Vector3 三维向量对象)
mesh.position.x = 5;
mesh.position.set(5,5,5);
// 2. 旋转 rotation 属性(Euler 欧拉角弧度制角度对象)
// x,z,y 从轴的正方向看去,值增加时,是逆时针绕轴旋转
mesh.rotation.x = Math.PI / 3
// 3. 缩放 scale 属性(Vector3 三维向量对象,中心原点不动,向 2 边拉伸/缩小)
mesh.scale.z = 2
// 配合键盘使用
window.addEventListener('keydown', e => {
switch (e.key) {
case 'd':
cube.position.x += 0.01
break;
case 'w':
cube.position.y += 0.01
break;
case 's':
cube.position.y -= 0.01
break;
case 'a':
cube.position.x -= 0.01
break;
}
})
function render() {
renderer.render(scene, camera)
mesh.rotation.x += 0.01
mesh.rotation.y += 0.01
requestAnimationFrame(render)
}
render()