【ThreeJS Basics 06】Camera

文章目录

  • [Camera 相机](#Camera 相机)
  • [PerspectiveCamera 透视相机](#PerspectiveCamera 透视相机)
  • 正交相机
  • 用鼠标控制相机
  • 控制组件
    • [FlyControls 飞行组件控制](#FlyControls 飞行组件控制)
    • [FirstPersonControls 第一人称控制](#FirstPersonControls 第一人称控制)
    • [PointerLockControls 指针锁定控制](#PointerLockControls 指针锁定控制)
    • [OrbitControls 轨道控制](#OrbitControls 轨道控制)
    • [TrackballControls 轨迹球控制](#TrackballControls 轨迹球控制)
    • [TransformControls 变换控制组件](#TransformControls 变换控制组件)
    • 拖拽组件
  • [尝试引入并使用控件:OrbitControls 轨道](#尝试引入并使用控件:OrbitControls 轨道)
  • [DAMPING 阻尼](#DAMPING 阻尼)

Camera 相机

以下是几种常见的相机简介

  • ArrayCamera : 数组相机
  • StereoCamera:双眼相机,可以使用两个相机来渲染场景,类似 VR,以及双人成行的屏幕分开的双人游戏
  • CubeCamera:立方体相机,有 6 个相机,分别渲染 6 个面,ThreeJS 可以用它来渲染环境,贴图,反射,折射阴影
  • OrthographicCamera:正交相机,RTS 游戏,相对于透视相机(透视相机更接近人眼的观察效果)
  • PerspectiveCamera:透视相机

PerspectiveCamera 透视相机

参数如下图所示

第一个参数是视野:建议的值在 45~75

如果视野足够大的话,那么规则的立方体可能被挤压变形,类似这样的效果

第二个参数是:横纵比,一般是画布的长/宽

javascript 复制代码
const sizes = {
    width: 800,
    height: 600
}

const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100)

第三个和第四个参数 nearfar

默认值是 1, 1000,意味着:
任何比近处更近,或者比远处更远的物体,都不会显示出来

选择合适的取值范围,如果远端有山庄,山脉,云朵之类的,可以取合适的值来判断是否渲染它们。


正交相机

正交相机有六个参数,前四个是位置,左右上下,第五个和第六个跟透视相机的参数类似,远近的渲染

javascript 复制代码
const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0.1, 100)

上面的形状并不规则,因为渲染的比例不对,我们获取

javascript 复制代码
const aspectRatio = sizes.width / sizes.height
// Camera 
// const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height)
const camera = new THREE.OrthographicCamera(-1 * aspectRatio, 1 * aspectRatio, 1, -1, 0.1, 100)
  • 正交相机不受透视影响,能保证物体形状不因深度而发生变化,适合 2D、UI、地图等场景。
  • 乘以 aspectRatio 让视口匹配屏幕比例,确保物体不会在不同设备下发生拉伸变形。
  • 如果你需要准确控制几何形状或在屏幕上保持形状固定,正交相机是更好的选择。

用鼠标控制相机

获取坐标位置,并处理坐标值的范围在 [-0.5, 0.5]

javascript 复制代码
/**
 * Cursor
 */
const cursor = {
  x: 0,
  y: 0,
}
window.addEventListener('mousemove', (event) => {
  cursor.x = event.clientX / sizes.width - 0.5
  cursor.y = event.clientY / sizes.height - 0.5
  console.log('cursor:>>', cursor)
})

之后再 tick 函数里更改相机的位置

javascript 复制代码
const tick = () => {
  const elapsedTime = clock.getElapsedTime()

  // Update objects
  //   mesh.rotation.y = elapsedTime
  camera.position.x = cursor.x * 10
  camera.position.y = cursor.y * 10
  camera.lookAt(mesh.position )

  // Render
  renderer.render(scene, camera)

  // Call tick again on the next frame
  window.requestAnimationFrame(tick)
}

但是这里会有奇怪的问题, 似乎 x 轴跟 y 轴的逻辑是反着的

所以改变一下 cursor.y 的值,整体取值负数,这样x,y轴都是反方向的了

或者 x 轴取负数,这样就是类似跟随鼠标的效果

但是这样有个问题:我看不到物体的后面,那么,如何才能看到后面呢?或者说让相机旋转起来


大幅度转动(可以看到后面)

javascript 复制代码
const tick = () => {
  const elapsedTime = clock.getElapsedTime()

  // Update objects
  //   mesh.rotation.y = elapsedTime
  camera.position.x = Math.sin(cursor.x * Math.PI * 2) * 3
  camera.position.z = Math.cos(cursor.x * Math.PI * 2) * 3
  camera.position.y = cursor.y * 5

  camera.lookAt(mesh.position)

  // Render
  renderer.render(scene, camera)

  // Call tick again on the next frame
  window.requestAnimationFrame(tick)
}

控制组件

FlyControls 飞行组件控制

演示地址点我: https://threejs.org/examples/#misc_controls_fly

FirstPersonControls 第一人称控制

https://threejs.org/examples/#webgl_geometry_terrain

PointerLockControls 指针锁定控制

https://threejs.org/examples/#misc_controls_pointerlock

OrbitControls 轨道控制

https://threejs.org/examples/#misc_controls_orbit

TrackballControls 轨迹球控制

https://threejs.org/examples/#misc_controls_trackball


TransformControls 变换控制组件

https://threejs.org/examples/#misc_controls_transform

拖拽组件

https://threejs.org/examples/#misc_controls_drag


尝试引入并使用控件:OrbitControls 轨道

导入

OrbitControls 它不在 THREE 这个变量中,需要手动的导入

javascript 复制代码
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'

const controls = new OrbitControls(camera, canvas)

两句话,就可以有下图的使用效果了

DAMPING 阻尼

拖拽的时候有些生涩,加入阻尼之后,会有一定的加速度

但是会有些奇怪,因为需要再每一帧上更新控件才能正常的显现,在 tick 函数中添加更新 controls.update()

相关推荐
入秋14 小时前
Three.js 实战之电子围栏可根据模型自动生成
前端·前端框架·three.js
答案answer2 天前
three.js着色器(Shader)实现数字孪生项目中常见的特效
前端·three.js
KallkaGo7 天前
threejs复刻原神渲染(三)
前端·webgl·three.js
刘皇叔code8 天前
如何给Three.js中ExtrudeGeometry的不同面设置不同材质
webgl·three.js
vivo互联网技术9 天前
拥抱新一代 Web 3D 引擎,Three.js 项目快速升级 Galacean 指南
前端·three.js
你真的可爱呀13 天前
5.Three.js 学习(基础+实践)
学习·three.js
战场小包15 天前
弟弟想看恐龙,用文心快码3.5S快速打造恐龙乐园,让弟弟看个够
前端·three.js·文心快码
入秋15 天前
Three.js后期处理实战:镜头颜色、色差、点阵与颜色管道的深度解析
前端·three.js