相机是Three.js
抽象出来的一个对象,使用此对象,我们可以定义显示的内容,并且可以通过移动相机位置来显示不同的内容。 下面讲解一下Three.js
中的相机的通用属性和常用的相机对象。
相机通用属性和方法
我们常用的相机正交相机(OrthographicCamera
)和透视相机(PerspectiveCamera
)两种相机,用于来捕获场景内显示的物体模型。它们有一些通用的属性和方法:
Object3D的所有属性和方法
由于相机都是继承至THREE.Object3D
对象的,所以像设置位置的position
属性、rotation
旋转和scale
缩放属性,可以直接对相机对象设置。我们甚至还可以使用add()
方法,给相机对象添加子类,移动相机它的子类也会跟随着一块移动,我们可以使用这个特性制作一些比如HUD
类型的显示界面。
target 焦点属性和lookAt()方法
这两个方法的效果一定,都是调整相机的朝向,可以设置一个THREE.Vector3
(三维向量)点的位置:
上面两个都是朝向了原点,我们也可以将相机的朝向改为模型网格的position
,如果物体的位置发生了变化,相机的焦点方向也会跟随变动:
getWorldDirection()
getWorldDirection()
方法可以获取当前位置到target
位置的世界中的方向。方向也可以使用THREE.Vector3
对象表示,所以该方法返回一个三维向量。
OrthographicCamera 正交相机
使用正交相机OrthographicCamera
渲染出来的场景,所有的物体和模型都按照它固有的尺寸和精度显示,一般使用在工业要求精度或者2D平面中,因为它能完整的显示物体应有的尺寸。
创建正交相机
上面的图片可以清晰的显示出正交相机显示的范围,它显示的内容是一个立方体结构,通过图片我们发现,只要确定top
,left
,right
,bottom
,near
和far
六个值,我们就能确定当前相机捕获场景的区域,在这个区域外面的内容不会被渲染,所以,我们创建相机的方法就是:
下面我们创建了一个显示场景中相机位置前方长宽高都为4的盒子内的物体的正交相机:
正常情况相机显示的内容需要和窗口显示的内容同样的比例才能够显示没有被拉伸变形的效果:
动态修改正交相机属性
我们也可以动态的修改正交相机的一些属性,注意修改完以后需要调用相机updateProjectionMatrix()
方法来更新相机显存里面的内容:
窗口变动后的更新
由于浏览器的窗口是可以随意修改,我们有时候需要监听浏览器窗口的变化,然后获取到最新的宽高比,再重新设置相关属性:
PerspectiveCamera 透视相机
透视相机是最常用的也是模拟人眼的视角的一种相机,它所渲染生成的页面是一种近大远小的效果。
创建透视相机
上面的图片就是一个透视相机的生成原理,我们先看看渲染的范围是如何生成的:
- 首先,我们需要确定一个
fov
值,这个值是用来确定相机前方的垂直视角,角度越大,我们能够查看的内容就越多。 - 然后,我们又确定了一个渲染的宽高比,这个宽高比最好设置成页面显示区域的宽高比,这样我们查看生成画面才不会出现拉伸变形的效果,这时,我们可以确定了前面生成内容的范围是一个四棱锥的区域。
- 最后,我们需要确定的就是相机渲染范围的最小值
near
和最大值far
,注意,这两个值都是距离相机的距离,确定完数值后,相机会显示的范围就是一个近小远大的四棱柱的范围,我们能够看到的内容都是在这个范围内的。
通过上面的原理,我们需要通过设置fov
垂直角度,aspect
视角宽高比例和near
最近渲染距离far
最远渲染距离,就能够确定当前透视相机的渲染范围。
下面,是一个透视相机的创建:
我们设置了前方的视角为45度,宽度和高度设置成显示窗口的宽度除以高度的比例即可,显示距离为1到1000距离以内的物体。
动态修改透视相机的属性
透视相机的属性创建完成后我们也可以根据个人需求随意修改,但是注意,相机的属性修改完成后,以后要调用updateProjectionMatrix()
方法来更新:
显示窗口变动后的回调
如果当前场景浏览器的显示窗口变动了,比如修改了浏览器的宽高后,我们需要设置场景自动更新,下面是一个常用的案例:
最后,我写了一个案例来查看透视相机和正交相机的显示区别:点击这里 左侧是透视相机显示的效果,这种更符合人眼看到的效果,场景更加的立体。而右侧则是正交相机实现的效果,渲染出来的数值更加的准确,但是却不符合人眼查看的效果。
案例代码查看地址:点击这里
制作相机控制器
在实际生产当中,我们有很多的需求就是切换相机的位置,来达到项目需求。 Three.js
也有很多相机控制插件,这个我们会在后面的课程当中讲解下面是我书写的一个小案例,能够通过鼠标左键拖拽界面让相机围绕模型周围查看模型。首先,先上案例地址:点击这里 代码查看地址:点击这里 其实和以前的代码相比,我们也只是多出来了一个initControl
方法,在这个方法里面绑定鼠标事件。实现的思路也很简单:
- 首先绑定鼠标按下事件,获取到按下时的相机位置和距离原点的距离,计算出来相对于
z
轴正方向的偏移。绑定鼠标移动事件。 - 然后,在鼠标移动事件里面获取到距离鼠标按下的偏移,通过鼠标偏移数值计算出现在相机位置,并赋值。
思路就这么简单,虽然实现起来会麻烦,我也尽量写的简单,大家尽量能够自己也写出来。