Three.js 文档:https://threejs.org/
哔哩哔哩配套视频学习教程地址:https://www.bilibili.com/video/BV1HPYQz7Ed2?spm_id_from=333.788.videopod.episodes&vd_source=628c735d0423e2bd1153ac15c47d3d87
我们可以通过调整配置轨道控制器的相关属性,从而优化影响摄像机的展示细节。主要介绍以下几个部分:
旋转物体时增加阻尼效果,可以想像一下日常生活的中家具柜门的阻尼效果,与此类似。
那么通过给已经创建的轨道控制对象设置属性enableDamping = true
来开启阻尼效果,默认不开启阻尼效果。
另外可以通过设置属性 dampingFactor
的值为一个 Float 类型的浮点值,来设置阻尼惯性的大小,默认值 0.05。
具体代码实现,定位 main.js 文件的 createControls 方法,做如下修改:
// file: src/main.js
// 创建轨道控制器
function createControls() {
controls = new OrbitControls(camera, renderer.domElement);
// 开启阻尼效果
controls.enableDamping = true;
}
有无阻尼效果对比:
通过给已经创建的轨道控制对象设置属性autoRotate = true
来开启自动旋转轨道控制器的效果,从而带动摄像机一起旋转。
具体代码实现,定位 main.js 文件的 createControls 方法,做如下修改:
// file: src/main.js
// 创建轨道控制器
function createControls() {
controls = new OrbitControls(camera, renderer.domElement);
// 开启阻尼效果
controls.enableDamping = true;
// 开启自动旋转
controls.autoRotate = true;
}
效果如下:
通过给已经创建的轨道控制对象设置属性minPolarAngle
和 maxPolarAngle
来控制相机能够垂直旋转的角度的上下限。
可以通过将二者设置为相同的值来禁用单个轴。
从上图可以看出,0 表示相机在上面,Math.PI 表示相机在下方。
具体代码实现,定位 main.js 文件的 createControls 方法,做如下修改:
// file: src/main.js
// 创建轨道控制器
function createControls() {
controls = new OrbitControls(camera, renderer.domElement);
// 开启阻尼效果
controls.enableDamping = true;
// 关闭自动旋转
controls.autoRotate = true;
// 设置垂直旋转的角度下限,范围是 0 ~ Math.PI,默认 0
controls.minPolarAngle = 0;
// 设置垂直旋转的角度上限,范围是 0 ~ Math.PI, 默认 Math.PI
controls.maxPolarAngle = Math.PI / 2;
}
上面示例代码配置效果(只能向下旋转90度,不能向上旋转)如下:
通过给已经创建的轨道控制对象设置属性minAzimuthAngle
和 maxAzimuthAngle
来控制相机能够水平旋转的角度的上下限。
可以通过将二者设置为相同的值来禁用单个轴。
具体代码实现,定位 main.js 文件的 createControls 方法,做如下修改:
// file: src/main.js
// 创建轨道控制器
function createControls() {
controls = new OrbitControls(camera, renderer.domElement);
// 设置阻尼效果 true / false
controls.enableDamping = true;
// 设置是否自动旋转 true / false
controls.autoRotate = false;
// 设置垂直旋转的角度下限,范围是 0 ~ Math.PI,默认 0
controls.minPolarAngle = 0.5 * Math.PI;
// 设置垂直旋转的角度上限,范围是 0 ~ Math.PI, 默认 Math.PI
controls.maxPolarAngle = 0.5 * Math.PI;
// 设置水平旋转的角度的下限,范围是 -2 * Math.PI 到 2 * Math.PI,其默认值为无穷大
controls.minAzimuthAngle = 0.5 * Math.PI;
// 设置水平旋转的角度的上限,范围是 -2 * Math.PI 到 2 * Math.PI,其默认值为无穷大
controls.maxAzimuthAngle = 1.5 * Math.PI;
}
上面示例代码配置效果(禁止垂直旋转,水平旋转不能看到前面,左右后三面可见)如下:
通过给已经创建的轨道控制对象设置属性minDistance
和 maxDistance
来控制相机向内或向外移动的最大范围。
具体代码实现,定位 main.js 文件的 createControls 方法,做如下修改:
// file: src/main.js
// 创建轨道控制器
function createControls() {
controls = new OrbitControls(camera, renderer.domElement);
// 设置阻尼效果 true / false
controls.enableDamping = true;
// 设置是否自动旋转 true / false
controls.autoRotate = false;
// 设置垂直旋转的角度下限,范围是 0 ~ Math.PI,默认 0
controls.minPolarAngle = 0.5 * Math.PI;
// 设置垂直旋转的角度上限,范围是 0 ~ Math.PI, 默认 Math.PI
controls.maxPolarAngle = 0.5 * Math.PI;
// 设置水平旋转的角度的下限,范围是 -2 * Math.PI 到 2 * Math.PI,其默认值为无穷大
controls.minAzimuthAngle = 0.5 * Math.PI;
// 设置水平旋转的角度的上限,范围是 -2 * Math.PI 到 2 * Math.PI,其默认值为无穷大
controls.maxAzimuthAngle = 1.5 * Math.PI;
// 设置相机能够向内最小移动多少
controls.minDistance = 2;
// 设置相机能够向外最大移动多少
controls.maxDistance = 10;
}
上面示例代码配置效果如下:
当浏览器窗口尺寸改变时,我们希望场景及其内部物体的尺寸可以自适应。
步骤:
具体代码实现,在 main.js 文件内增加一个 resizeRender 的方法,下面是 main.js 文件的完整代码:
// file: src/main.js
// 引入 three.js
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// 场景,摄像机,渲染器
let scene, camera, renderer;
// 轨道控制器
let controls;
// 立方体
let cube;
// 初始化三要素
function init() {
// 1. 创建场景对象
scene = new THREE.Scene();
// 2. 创建摄像机对象
// 参数1:垂直角度(建议75),视野范围
// 参数2:宽高比(建议与画布相同宽高),物体绘制比例
// 参数3:近截面距离摄像机距离
// 参数4:远截面距离摄像机距离
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// 移动摄像机 z 轴 5 个单位(默认摄像机和物体的坐标轴的都在原点)
camera.position.z = 5;
// 3. 创建渲染器
renderer = new THREE.WebGLRenderer({
antialias: true, // 开启抗锯齿 - 优化
});
renderer.setSize(window.innerWidth, window.innerHeight); // 设置画布大小
document.body.append(renderer.domElement); // 添加到DOM显示
}
// 创建立方体
function createCube() {
// 1. 创建图形,宽深高为 1 单位(立体缓冲几何体)
const geometry = new THREE.BoxGeometry(1, 1, 1);
// 2. 创建材质,颜色为绿色 0x00ff00 (网格基础材质 - 线面纯颜色描绘表面)
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
// 3. 创建网格物体对象,传入图形和材质(网格物体对象)
cube = new THREE.Mesh(geometry, material);
// 4. 把物体加入到场景中
scene.add(cube);
}
// 创建轨道控制器
function createControls() {
controls = new OrbitControls(camera, renderer.domElement);
// 设置阻尼效果 true / false
controls.enableDamping = true;
// 设置是否自动旋转 true / false
controls.autoRotate = false;
// 设置垂直旋转的角度下限,范围是 0 ~ Math.PI,默认 0
// controls.minPolarAngle = 0.5 * Math.PI;
// 设置垂直旋转的角度上限,范围是 0 ~ Math.PI, 默认 Math.PI
// controls.maxPolarAngle = 0.5 * Math.PI;
// 设置水平旋转的角度的下限,范围是 -2 * Math.PI 到 2 * Math.PI,其默认值为无穷大
// controls.minAzimuthAngle = 0.5 * Math.PI;
// 设置水平旋转的角度的上限,范围是 -2 * Math.PI 到 2 * Math.PI,其默认值为无穷大
// controls.maxAzimuthAngle = 1.5 * Math.PI;
// 设置相机能够向内最小移动多少
// controls.minDistance = 2;
// 设置相机能够向外最大移动多少
// controls.maxDistance = 10;
}
/**
* 渲染循环
*/
function renderLoop() {
renderer.render(scene, camera);
// 手动 JS 代码更新过摄像机信息,必须调用轨道控制器 update 方法
controls.update();
// 根据当前计算机浏览器刷新帧率(默认 60 次/秒),不断递归调用此函数渲染最新的画面状态
// 好处:当前页面切换到后台,暂停递归
requestAnimationFrame(renderLoop);
}
// 添加坐标轴辅助对象
function createHelper() {
/**
* 用于简单模拟3个坐标轴的对象.
* 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴.
*/
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);
}
/**
* 优化 - 适配场景大小
*/
function resizeRender() {
window.addEventListener('resize', () => {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
});
}
// 初始化元素
init();
// 创建轨道控制器
createControls();
// 添加坐标轴
createHelper();
// 场景自适应适配
resizeRender();
// 创建立方体
createCube();
// 渲染循环
renderLoop();
效果如下:
通过本文的学习,我们要充分理解和体会物体和摄像机的空间立体感,个人觉得这个至关重要,物体是不动的,我们所看到的物理的旋转和位移,实际上是摄像机在移动,只有理解了这个基础且重要的相对概念,才能更好的进行学习。
🔥BuildAdmin是一个永久免费开源,无需授权即可商业使用,且使用了流行技术栈快速创建商业级后台管理系统。