

three.js三要素
场景(scene) 摄像机(camera) 渲染器(renderer)
- 下载并引入three库
css
npm i three
javascript
import * as THREE from 'three'
- 创建场景对象
javascript
let scene,camera,renderer // 场景 摄像机 渲染器
function init () {
// 创建场景对象
scene = new THREE.Scene()
// 创建摄像机对象
// 参数1:垂直角度(建议75),视野范围
// 参数2:宽高比(建议与画布相同宽高)物体绘制比例
// 参数3:近截面距离摄像机距离
// 参数4:远截面距离摄像机距离
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
// 创建渲染器,并设置画布大小,添加到DOM显示
renderer = new THREE.WebGLRenderer()
// 设置画布大小
renderer.setSize(window.innerWidth, window.innerHeight)
// 把画布canvas标签添加到页面上
document.body.append(renderer.domElement)
// 传入场景和摄像机,渲染画面
renderer.render(scene,camera)
}

画出一个立方体

xml
<template>
<div></div>
</template>
<script setup>
import * as THREE from "three";
import { onMounted } from "vue";
let scene, camera, renderer; // 场景 摄像机 渲染器
const init = () => {
// 创建场景对象
scene = new THREE.Scene();
// 创建摄像机对象
// 参数1:垂直角度(建议75),视野范围
// 参数2:宽高比(建议与画布相同宽高)物体绘制比例
// 参数3:近截面距离摄像机距离
// 参数4:远截面距离摄像机距离
camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
// 创建渲染器,并设置画布大小,添加到DOM显示
renderer = new THREE.WebGLRenderer();
// 设置画布大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 把画布canvas标签添加到页面上
document.body.append(renderer.domElement);
// 传入场景和摄像机,渲染画面
};
// 创建立方体
const createCube = () => {
// 1.创建图形,宽高深为1单位(立方缓冲几何体)
const geometry = new THREE.BoxGeometry(1, 1, 1);
// 2.创建网格物体对象,传入图形和材质(网格基础材质-线面纯颜色绘制表面)
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
// 3.创建网格物体对象,传入图形和材质(网格物体对象)
const cube = new THREE.Mesh(geometry, material);
// 4.把物体添加到场景中
scene.add(cube);
// 移动摄像机向Z轴移动5个单位 (默认摄像机和物体的坐标轴都在远点)
camera.position.z = 5;
};
onMounted(() => {
// 初始化
init();
// 创建立方体
createCube()
renderer.render(scene, camera);
});
</script>
<style lang="scss" scoped></style>
轨道控制器OrbitControls
使用:
- 单独引入 OrbitControls 轨道控制器构造函数
- 创建轨道控制器
- 在渲染循环中更新场景渲染
创建轨道控制时候的两个参数:
相机camera
渲染器的DOM元素renderer.domElement
使用相机作为第一个参数是为了将轨道控制器绑定到特定的相机上,以便对相机进行交互控制。
使用渲染器的 DOM 元素作为第二个参数是为了让轨道控制器监听鼠标和触摸事件,并根据用户的输入进行相应的操作,比如旋转、缩放和平移相机。
javascript
// 目标:摄像机 - 轨道控制器
// 作用:调整摄像机位置等,查看不同画面
// 1. 单独引入 OrbitControls 轨道控制器构造函数
// 2. 创建轨道控制器
// 3. 在渲染循环中更新场景渲染
import * as THREE from 'three'
// 1. 单独引入 OrbitControls 轨道控制器构造函数
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
// 场景,摄像机,渲染器
let scene, camera, renderer
// 轨道控制器
let controls
function controlsCreate() {
// 2. 创建轨道控制器
controls = new OrbitControls( camera, renderer.domElement )
}
function renderLoop() {
// 3. 在渲染循环中更新场景渲染
renderer.render(scene, camera)
// 手动 JS 代码更新过摄像机信息,必须调用轨道控制器 update 方法
controls.update()
// 根据当前计算机浏览器刷新帧率(默认 60 次/秒),不断递归调用此函数渲染最新的画面状态
// 好处:当前页面切换到后台,暂停递归
requestAnimationFrame(renderLoop)
}
xml
<template>
<div></div>
</template>
<script setup>
import * as THREE from "three";
import { onMounted } from "vue";
// 1. 单独引入 OrbitControls 轨道控制器构造函数
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
// 目标:摄像机 - 轨道控制器
// 作用:调整摄像机位置等,查看不同画面
// 1. 单独引入 OrbitControls 轨道控制器构造函数
// 2. 创建轨道控制器
// 3. 在渲染循环中更新场景渲染
let scene, camera, renderer; // 场景 摄像机 渲染器
// 2. 创建轨道控制器
let controls;
onMounted(() => {
// 初始化
init();
// 创建轨道控制器
getcontrols();
// 创建立方体
createCube();
// 更新场景渲染
renderLoop();
// 创建坐标轴
createHelper();
});
const getcontrols = () => {
controls = new OrbitControls(camera, renderer.domElement);
};
// 3. 在渲染循环中更新场景渲染
const renderLoop = () => {
requestAnimationFrame(renderLoop);
controls.update();
renderer.render(scene, camera);
};
const init = () => {
// 创建场景对象
scene = new THREE.Scene();
// 创建摄像机对象
// 参数1:垂直角度(建议75),视野范围
// 参数2:宽高比(建议与画布相同宽高)物体绘制比例
// 参数3:近截面距离摄像机距离
// 参数4:远截面距离摄像机距离
camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
// 创建渲染器,并设置画布大小,添加到DOM显示
renderer = new THREE.WebGLRenderer();
// 设置画布大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 把画布canvas标签添加到页面上
document.body.append(renderer.domElement);
// 传入场景和摄像机,渲染画面
};
// 创建立方体
const createCube = () => {
// 1.创建图形,宽高深为1单位(立方缓冲几何体)
const geometry = new THREE.BoxGeometry(1, 1, 1);
// 2.创建网格物体对象,传入图形和材质(网格基础材质-线面纯颜色绘制表面)
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
// 3.创建网格物体对象,传入图形和材质(网格物体对象)
const cube = new THREE.Mesh(geometry, material);
// 4.把物体添加到场景中
scene.add(cube);
// 移动摄像机向Z轴移动5个单位 (默认摄像机和物体的坐标轴都在远点)
camera.position.z = 3;
};
// 创建坐标轴
const createHelper = () => {
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);
};
</script>
<style lang="scss" scoped></style>
坐标轴
坐标轴:在画布模拟 3 个坐标轴(x,y,z),随时显示和调整,辅助我们开发和调试
使用:
csharp
// 创建一个坐标轴辅助工具
function createHelper() {
// 1. 创建坐标轴对象,设置长度
const axesHelper = new THREE.AxesHelper(5)
// 2. 添加到场景中
scene.add(axesHelper)
}
注意:因为浏览器兼容性,线段最大最小宽度只能为 1
three.js 和 WebGL 一样,采用右手坐标系,借助 AxesHelper 往场景中加入了一个 x,y,z 的坐标轴辅助对象
轨道控制器-控制
文档地址:three.js中文文档
下面属性都是在轨道控制器这个对象上面设置,需要在轨道控制中去修改属性
1.阻尼效果 enableDamping
可以通过修改dampingFactor属性来增加阻尼效果,这个参数的值为Float浮点型,默认值是0.05
要想这一个值生效,必须要在你的动画循环里面调用update()
dampingFactor属性值越小,阻尼效果越明显
2.自动顺时针旋转 autoRotate
3.垂直范围控制
- maxPolarAngle
设置垂直旋转的角度上限,范围是0到Math.PI,默认值是Math.PI
- minPolarAngle
设置垂直旋转的角度下限,范围是0到Math.PI,默认值是
- 水平范围控制
- maxAzimuthAngle(马克思艾贼美四昂狗)
你能够水平旋转的角度上限。如果设置,其有效值范围为[-2 * Math.PI,2 * Math.PI],且旋转角度的上限和下限差值小于2 * Math.PI。默认值为无穷大。
- minAzimuthAngle
你能够水平旋转的角度下限。如果设置,其有效值范围为[-2 * Math.PI,2 * Math.PI],且旋转角度的上限和下限差值小于2 * Math.PI。默认值为无穷大。
- 移动范围控制
- minDistance
你能够将相机向内移动多少(仅适用于PerspectiveCamera),其默认值为0。
- maxDistance
你能够将相机向外移动多少(仅适用于PerspectiveCamera),其默认值为Infinity。
ini
function controlsCreate() {
controls = new OrbitControls(camera, renderer.domElement)
// 1. 阻尼效果
controls.enableDamping = true
// 2. 开启自动旋转轨道控制器效果->带动摄像机一起旋转(摄像机顺时针水平旋转)
// controls.autoRotate = true
// 3. 垂直角度范围控制(0 上面,Math.PI 下面)
controls.maxPolarAngle = Math.PI
controls.minPolarAngle = 0
// 水平角度范围控制
controls.maxAzimuthAngle = 1.5 * Math.PI
controls.minAzimuthAngle = 0.5 * Math.PI
// 4. 摄像机移动范围控制
controls.minDistance = 2
controls.maxDistance = 10
}

