当前位置: 首页 > news >正文

Three.js轨道控制器完全指南(OrbitControls与TrackballControls)

文章目录

  • 目标
  • 轨道控制器(OrbitControls)介绍
    • 基本功能
    • 主要特点
    • 适用场景
  • 实现及演示过程
    • 阻尼效果
    • 旋转
    • 平移
    • 缩放
    • 控制范围
    • 完整代码
  • TrackballControls 介绍(与OrbitControls的差异)
    • 控制方式差异
    • 使用场景
    • 技术特性
    • 性能表现
    • 代码配置示例
    • 选择建议

目标

  • 了解轨道控制器(OrbitControls与TrackballControls)
  • 开始使用轨道控制器OrbitControls(TrackballControls只介绍其功能,不实现其功能)

轨道控制器(OrbitControls)介绍

基本功能

OrbitControls 是 Three.js 库中提供的一个控制器组件,主要用于实现三维场景的交互式观察功能。它允许用户通过鼠标或触摸屏控制相机在3D场景中的位置和视角,从而实现对场景的自由探索。

主要特点

  • 旋转控制:用户可以通过拖拽鼠标左键(或单指触摸)来旋转相机,围绕场景中心点进行360度全方位观察。
  • 缩放控制:通过鼠标滚轮(或双指捏合)可以放大或缩小场景,改变相机与目标点之间的距离。
  • 平移控制:按住鼠标右键(或双指拖动)可以平移整个场景,改变观察的中心位置。
  • 阻尼效果:控制器内置了平滑的阻尼效果,使操作更加自然,不会突然停止。
  • 限制范围:可以设置旋转角度、缩放距离和平移范围的限制,防止相机移动到不合理的位置。

适用场景

3D 场景导航、模型查看、交互式演示

实现及演示过程

  • 引入 OrbitControls 模块
  • 初始化控制器并与相机、渲染器绑定
// 轨道控制
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'// 轨道控制器
let controls: OrbitControls// 添加控制器
function initControls() {controls = new OrbitControls(camera, canvasThree.value)
}

阻尼效果

// 阻尼
controls.enableDamping = true // 开启阻尼效果
controls.dampingFactor = 0.05 // 停下来的速度,设置的越小,效果越明显

在我们用鼠标去旋转物体时,当我们松开鼠标,物体会缓慢的停下来,如下图所示:

在这里插入图片描述

旋转

controls.autoRotate = true // 开启自动旋转
controls.autoRotateSpeed = 0.5 // 设置旋转速度

这里我们开启自动旋转的效果,是绕y轴的旋转,如下图,另外,我们按住鼠标左键上下移动鼠标,可以实现绕x轴的旋转;至于绕z轴的旋转,可以通过其他的方式实现。

在这里插入图片描述

平移

// controls.enablePan = false
// controls.panSpeed = 0.05

平移是默认开启的,我们按住鼠标右键就可以拖动,效果如下,当然,也可使用上面代码去禁止拖动

在这里插入图片描述

缩放

// controls.enableZoom = false
// controls.zoomSpeed = 0.05

默认开启
我们可以根据上面代码进行关闭,这里效果就略了,就是使用鼠标滚轮来进行缩放。

控制范围

  // 范围// 缩放范围controls.minDistance = 1controls.maxDistance = 100// 角度范围(垂直角度:x轴)—— 极角(Polar angle):绕X轴旋转(上下移动视角)controls.maxPolarAngle = Math.PI / 2controls.minPolarAngle = 0// 角度范围(水平角度:y轴)—— 方位角(Azimuth angle):绕Y轴旋转(左右移动视角)controls.maxAzimuthAngle = Math.PIcontrols.minAzimuthAngle = -Math.PI
  • 通过以上代码对范围进行控制
  • 1.缩放范围的控制到1-100,到一定程度就不能再缩放了,这个没有默认,但是有设置的必要。
  • 2.角度范围,上面分别给出了绕x轴与绕y轴的旋转角度范围,设置之后,也是会控制到一定范围,不可以继续旋转。

完整代码

在完整代码中,除了实现上述的效果代码,另外,可以开启绕z轴的自动旋转,自己参考:

在这里插入图片描述

<script setup lang="ts">
import type { GLTF } from 'three/addons/loaders/GLTFLoader.js'
import * as THREE from 'three'// 轨道控制
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'// RoomEnvironment用于创建一个室内环境,通常用来为3D场景提供基础的环境光照和反射效果,让3D模型在场景中看起来更加真实自然。
import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'
// DRACOLoader是一个用于加载和解码Google Draco压缩格式3D模型的加载器,可以减小3D模型文件大小,提高加载效率。
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'
// GLTFLoader用于加载GLTF格式的3D模型文件,这是Three.js的一个扩展加载器。
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'// 该组件用于在3D场景中提供变换控制功能(如移动、旋转、缩放),允许用户通过可视化控件直接操作3D对象。
import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js'import { onMounted, ref } from 'vue'const canvasThree = ref()// 创建scene、camera、renderer
let scene: THREE.Scene, camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer, model: THREE.Grouplet transformControls: TransformControls
// 添加Z轴旋转变量
const autoRotateZ = false
const rotationSpeedZ = 0.01// 轨道控制器
let controls: OrbitControls
// 动画混合器
let mixer: THREE.AnimationMixer// 添加控制器
function initControls() {controls = new OrbitControls(camera, canvasThree.value)// 阻尼controls.enableDamping = truecontrols.dampingFactor = 0.05// 旋转// 自动旋转(绕y轴)// controls.autoRotate = true// controls.autoRotateSpeed = 0.5// z轴旋转使用TransformControls或自定义控制逻辑来实现绕Z轴旋转。// 平移// controls.enablePan = false// controls.panSpeed = 0.05// 缩放// controls.enableZoom = false// controls.zoomSpeed = 0.05// 范围// 缩放范围controls.minDistance = 1controls.maxDistance = 100// 角度范围(垂直角度:x轴)—— 极角(Polar angle):绕X轴旋转(上下移动视角)controls.maxPolarAngle = Math.PI / 2controls.minPolarAngle = 0// 角度范围(水平角度:y轴)—— 方位角(Azimuth angle):绕Y轴旋转(左右移动视角)controls.maxAzimuthAngle = Math.PIcontrols.minAzimuthAngle = -Math.PI
}// 1.创建场景
function initScene() {scene = new THREE.Scene()
}// 2.创建相机
function initCamera() {camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,1000,)camera.position.set(0, 0, 10)scene.add(camera)
}// 3.创建物体(几何体 + 材质 = 物体)
// function initCube() {
//   const boxWidth = 1
//   const boxHeight = 1
//   const boxDepth = 1
//   const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth)//   const material = new THREE.MeshBasicMaterial({ color: 0x44AA88 })//   cube = new THREE.Mesh(geometry, material)//   scene.add(cube)
// }// 添加模型
function initModel() {const loader = new GLTFLoader()loader.setDRACOLoader(new DRACOLoader().setDecoderPath('../jsm/'))loader.load('../models/gltf/LittlestTokyo.glb', setModel, undefined, (e) => {console.error(e)})// 初始化模型function setModel(gltf: GLTF) {model = gltf.scenemodel.position.set(2, 1, 0)model.scale.set(0.02, 0.02, 0.02)scene.add(model)initMixer(gltf)// 将TransformControls附加到模型上,这样你就可以手动操作它了if (transformControls) {transformControls.attach(model)}}// 初始化动画混合器function initMixer(gltf: GLTF) {mixer = new THREE.AnimationMixer(gltf.scene) // 创建动画混合器播放模型动画if (gltf.animations[0]) {mixer.clipAction(gltf.animations[0]).play()}}
}// 添加环境
function initEenvironment() {scene.environment = new THREE.PMREMGenerator(renderer).fromScene(new RoomEnvironment(), 0.04).texture
}function initTransformControls() {transformControls = new TransformControls(camera, renderer.domElement)// Attach to an object to control it// transformControls.attach(objectToControl);// Switch between modestransformControls.mode = 'translate' // or 'rotate' or 'scale'scene.add(transformControls as unknown as THREE.Object3D)// Listen for changes and disable orbit controls while transformingtransformControls.addEventListener('dragging-changed', (event) => {controls.enabled = !event.value})// 添加键盘控制来切换模式window.addEventListener('keydown', (event) => {switch (event.key) {case 't': // Translate modetransformControls.mode = 'translate'breakcase 'r': // Rotate modetransformControls.mode = 'rotate'breakcase 's': // Scale modetransformControls.mode = 'scale'break}})
}// 4.渲染场景
function initRenderer() {// 创建渲染器renderer = new THREE.WebGLRenderer({ antialias: true, canvas: canvasThree.value })// 设置渲染器尺寸renderer.setSize(window.innerWidth, window.innerHeight)
}const clock = new THREE.Clock()
// 5.动画循环渲染场景
function animate() {requestAnimationFrame(animate)mixer && mixer.update(clock.getDelta()) // 更新3D模型的动画controls.update()// 如果启用了自动绕Z轴旋转if (autoRotateZ && model) {model.rotation.z += rotationSpeedZ}// 渲染场景renderer.render(scene, camera)
}onMounted(() => {// 初始化场景、相机、渲染器、物体initScene()initCamera()initRenderer()initControls()initTransformControlsinitModel()initEenvironment()// 启动动画循环animate()
})
</script><template><canvas id="canvasThree" ref="canvasThree" />
</template>

TrackballControls 介绍(与OrbitControls的差异)

  • TrackballControls 也是 Three.js 中常用的控制器之一,主要用于实现三维场景的交互控制。以下是与 OrbitControls 的详细对比:

控制方式差异

  • TrackballControls:允许摄像机自由旋转,不受"上下"方向的限制,可以全方位旋转
  • OrbitControls:模拟轨道运动,保持固定的上下方向(类似地球绕太阳旋转)

使用场景

  • TrackballControls 更适合:
    • 需要完全自由旋转的3D展示(如产品全方位展示)
    • 科学可视化应用中需要任意角度观察数据
    • 3D建模工具中的自由视角查看
  • OrbitControls 更适合:
    • 建筑可视化中的固定视角浏览
    • 地图类应用的有限角度查看
    • 需要保持"地面在下"的常规3D场景

技术特性

  • TrackballControls 提供:
    • 动态阻尼效果(可配置阻尼系数)
    • 可调节的旋转速度(通过设置rotateSpeed参数)
    • 缩放限制控制(minDistance/maxDistance)
    • 平移限制控制(maxDistance)
  • OrbitControls 提供:
    • 自动水平面保持
    • 明确的旋转范围限制
    • 更简单的API配置

性能表现

  • TrackballControls 计算量稍大,因为需要处理更复杂的旋转逻辑
  • OrbitControls 性能略优,适合性能敏感场景

代码配置示例

// TrackballControls 配置
controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.rotateSpeed = 2.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;// OrbitControls 配置
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.screenSpacePanning = false;
controls.minDistance = 1;
controls.maxDistance = 1000;
controls.maxPolarAngle = Math.PI;

选择建议

  • 当需要完全自由的3D观察体验时选择TrackballControls
  • 当需要保持常规视角和简单控制时选择OrbitControls
  • 在移动设备上,OrbitControls通常能提供更好的用户体验TrackballControls 比较
  • PointerLockControls 适用场景
  • 自定义控制器开发思路
http://www.dtcms.com/a/482924.html

相关文章:

  • 服务器数据恢复—硬盘黄灯预警,RAID5阵列数据如何恢复?
  • CATIA 转换为 3DXML 全流程:迪威模型网在线转换和本地方转换方法指南
  • 学校门户网站建设的意义做任务分享赚钱的网站
  • 网站个人中心wordpress怎么做手机网站
  • 杂记 15
  • Video Understanding Baseline via papers
  • MySQL架构和存储引擎
  • Zabbix模板,自定义键值监控项,图形
  • 前端js 常见算法面试题目详解
  • 盾思途旅游网站建设免费seo工具
  • 吴江区经济开发区建设工程网站网站对于企业的好处
  • 新的pvc是否可以指定pv, 而这个pv已经被另一个pvc绑定,状态为bound
  • 网站域名在哪里买巩义网站建设案例
  • 微软宣布删除“另存为”选项,今后文件将默认保存到云盘
  • 单北斗GNSS形变监测系统在桥梁安全中的应用与技术解析
  • 大兴网站建设公司网站架构设计师工资水平
  • 无人机远程无线图传技术详解,无人机图像传输技术解析,无人机wifi图传距离多远
  • 《3D山地场景渲染进阶:GPU驱动架构下细节与性能平衡的6大技术实践》
  • 热门搜索怎么做企业网站优化需要多少钱
  • JVM初识
  • 最小二乘问题详解4:非线性最小二乘
  • pcba方案开发|车载智能充气泵
  • c++项目篇:高并发内存池项目开发记录01
  • wordpress wp_term_taxonomy优化网站哪家好
  • 怎么选择宜昌网站建设沈阳网站建设与开发
  • SQL提数与数据分析指南
  • 新手用Godot打造2D像素风游戏
  • 框架--SpringMVC
  • 做外贸网站注意wordpress 附件下载插件
  • 微波人体传感器技术深度解析:从多普勒效应到工程落地