three.js镜头追踪的移动效果

该博客详细介绍了在three.js中如何实现镜头沿着折线路径移动的思路和方法,包括镜头控制难点及解决方案,如折线变曲线、镜头朝向、位置绑定等问题,并比较了不同实现方式的效果,如直线推进和tween动画。最终,博主推荐了使用tween动画的方法,以获得更平滑的镜头切换效果。
摘要由CSDN通过智能技术生成

达到效果

指定一条折线路径,镜头沿着路径向前移动,类似第一视角走在当前路径上。

实现思路

很简单画一条折线路径,将镜头位置动态绑定在当前路径上,同时设置镜头朝向路径正前方。

实现难点

1、折现变曲线
画一条折线路径,通常将每一个转折点标出来画出的THREE.Line,会变成曲线。
难点解答:
1.1、以转折点分隔,一段一段的直线来画,上一个线段的终点是下一个线段的起点。
1.2、画一条折线,在转折点处,通过多加一个点,构成一个特别细微的短弧线。
2、镜头朝向不受控
对于controls绑定的camera,修改camera的lookAt和rotation并无反应。
难点解答:
相机观察方向camera.lookAt设置无效需要设置controls.target
3、镜头位置绑定不受控
对于controls绑定的camera,动态修改camera的位置总存在一定错位。
难点解答:
苍天啊,这个问题纠结我好久,怎么设置都不对,即便参考上一个问题控制controls.object.position也不对。
结果这是一个假的难点,镜头位置是受控的,感觉不受控是因为,设置了相机距离原点的最近距离!!!导致转弯时距离太近镜头会往回退着转弯,碰到旁边的东西啊,哭唧唧。

// 设置相机距离原点的最近距离 即可控制放大限值
// controls.minDistance = 4
// 设置相机距离原点的最远距离 即可控制缩小限值
controls.maxDistance = 40

4、镜头抖动
镜头抖动,怀疑是设置位置和朝向时坐标被四舍五入时,导致一会上一会下一会左一会右的抖动。
难点解答:
开始以为是我整个场景太小了,放大场景,拉长折线,拉远相机,并没有什么用。
最后发现是在animate()动画中设置相机位置,y坐标加了0.01:

controls.object.position.set(testList[testIndex].x, testList[testIndex].y + 0.01, testList[testIndex].z)

相机位置坐标和相机朝向坐标不在同一平面,导致的抖动,将+0.01去掉就正常了。

controls.object.position.set(testList[testIndex].x, testList[testIndex].y, testList[testIndex].z)

最终实现方法

在此通过两个相机,先观察相机cameraTest的移动路径和转向,再切换成原始相机camera。
公共代码如下:

// 外层相机,原始相机
let camera = null
// 内层相机和相机辅助线
let cameraTest = null
let cameraHelper = null
// 控制器
let controls = null
// 折线点的集合和索引
let testList = []
let testIndex = 0

initCamera () {
  // 原始相机
  camera = new THREE.PerspectiveCamera(45, div3D.clientWidth / div3D.clientHeight, 0.1, 1000)
  camera.position.set(16, 6, 10)
  // scene.add(camera)
  // camera.lookAt(new THREE.Vector3(0, 0, 0))
  // 设置第二个相机
  cameraTest = new THREE.PerspectiveCamera(45, div3D.clientWidth / div3D.clientHeight, 0.1, 1000)
  cameraTest.position.set(0, 0.6, 0)
  cameraTest.lookAt(new THREE.Vector3(0, 0, 0))
  cameraTest.rotation.x = 0
  // 照相机帮助线
  cameraHelper = new THREE.CameraHelper(cameraTest)
  scene.add(cameraTest)
  scene.add(cameraHelper)
}
// 初始化控制器
initControls () {
  controls = new OrbitControls(camera, renderer.domElement)
}

方法一:镜头沿线推进

inspectCurveList () {
  let curve = new THREE.CatmullRomCurve3([
    new THREE.Vector3(2.9, 0.6, 7),
    new THREE.Vector3(2.9, 0.6, 1.6),
    new THREE.Vector3(2.89, 0.6, 1.6), // 用于直角转折
    new THREE.Vector3(2.2, 0.6, 1.6),
    new THREE.Vector3(2.2, 0.6, 1.59), // 用于直角转折
    new THREE.Vector3(2.2, 0.6, -5),
    new THREE.Vector3(2.21, 0.6, -5), // 用于直角转折
    new THREE.Vector3(8, 0.6, -5),
    new THREE.Vector3(8, 0.6, -5.01), // 用于直角转折
    new THREE.Vector3(8, 0.6, -17),
    new THREE.Vector3(7.99, 0.6, -17), // 用于直角转折
    new THREE.Vector3(-1, 0.6, -17),
    // new THREE.Vector3(-2, 0.6, -17.01), // 用于直角转折
    new THREE.Vector3(-3, 0.6, -20.4),
    new THREE.Vector3(-2, 0.6, 5)
  ])
  let geometry = new THREE.Geometry()
  let gap = 100
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值