Babylonjs中的常用相机

Babylon.js中摄影者相机

相机是3D世界中的摄影者,我们在显示器上看到的东西 ,都是相机拍摄出来的。想一想,现实生活中,相机变化了位置,那么相机中的液晶屏幕显示的内容是不是会变化呢?

所以,最终的呈现效果绝对与相机的位置、方向、镜头有关的。

在BabylonJs里的众多相机中使用最多的有两种—— Babylon.js通用相机(the Universal Camera)一般用于第一人称的活动, Babylon.js弧形旋转相机( the Arc Rotate Camera )是一种轨道相机。

为了鼠标能够控制相机,所以需要让相机关联画布,代码如下:

camera.attachControl(canvas, true);

第二个参数是可选的,默认值为false。当参数为false时,可以阻止画布事件上的默认操作;而当其设置为true时,则允许画布默认操作。


什么是通用相机(Universal Camera)

这里介绍的Babylon.js中的通用相机,可以通过使用键盘、鼠标、触摸板、游戏手柄输入控制。它延伸和替代了仍然可以使用的自由相机(Free Camera)、触摸相机(Touch Camera)和游戏手柄相机(Gamepad Camera)。

现在通用相机在没有特殊需求的情况下被BabylonJs用做默认相机。同时如果你想要在你的场景里使用 第一人称视角,它也是你最好的选择。

什么是第一人称视角:第一人称视角就是以你的视角进行,若用游戏比喻的话就是CS的初始视角,你只能看到别人不能看到自己全身,如下图:

babylonjs第一人称视角


BABYLON.UniversalCamera通用相机函数原型

BABYLON.UniversalCamera的函数原型是,

UniversalCamera(name: string, position: Vector3, scene: Scene): UniversalCamera
  • 参数name:相机的名字

  • 参数position:相机的初始位置

  • 参数scene:相机被放到哪个场景中

  • 返回:返回一个UniversalCamera相机变量

看一下实际的效果和代码:

babylonjs通用相机

预览效果12.html

//参数:名字,位置,所属场景
var camera = new BABYLON.UniversalCamera("UniversalCamera", new BABYLON.Vector3(0, 0, -10), scene);
//给相机的目标设置特定的位置(相机总是朝向它的目标),在这个例子中设置为场景的原点
camera.setTarget(BABYLON.Vector3.Zero());
//将相机和画布关联
camera.attachControl(canvas, true);

上面的第一行,将相机放到了(0,0,-10)的位置, setTarget表示相机注释的位置。

  • 现在你可以点击浏览器,然后移动键盘了。左右箭头(方向键 ← →)控制相机左右移动,向上和向下箭头(方向键 ↑ ↓ )控制相机向前和向后移动;

  • 鼠标移动:以摄像机为原点旋转摄像机,所以你可以看到物体围绕摄像机在转。

  • 触摸:左右滑动,左右移动相机,上下滑动,前后移动;

  • 手柄:设备上对应的按键控制方向和移动。好了,你应该没有手柄,所以不理解也没关系,哈哈。微软就是考虑全面,希望你购买xbox,所以手柄也支持。


什么是弧度旋转相机(Arc Rotate Camera)

弧度旋转相机这个相机名字听上去就很古怪,但是还算好,比较好理解。

这个相机总是指向一个给定的目标位置,并且可以围绕目标旋转,目标是旋转的中心。它可以用鼠标来控制,也可以用触摸事件来控制。

想象一下,这个相机其实就是一个间谍卫星绕地球旋转,可以将期各个方位的细节展示出来。其相对于目标的位置(地球)可以设置三个参数,α(弧度)的纵向旋转,β(弧度)横向旋转以及与目标的距离。

如下图:

弧度旋转相机是怎么旋转的

仔细看一下上面这幅图,你可能能明白意思。


ArcRotateCamera构造函数

ArcRotateCamera的构造函数如下:

ArcRotateCamera(name: string, alpha: number, beta: number, radius: number, target: Vector3, scene: Scene, setActiveOnSceneIfNoneActive?: boolean): ArcRotateCamera
  • name: 相机的名字
  • alpha: 相机的纵向旋转弧度
  • beta: 相机的横向旋转弧度
  • radius: 定义相机到目标观察点的距离
  • target: 定义相机的目标观察点
  • scene: 相机要加入的场景

下面是一个弧度旋转相机的例子:

// 参数:纵向旋转角度alpha、横向旋转角度beta、半径、目标位置、所属场景
var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, new BABYLON.Vector3(0, 0, 0), scene);
// 这是相机的位置,覆盖相机的alpha、beta、半径值
camera.setPosition(new BABYLON.Vector3(0, 0, -20));
// 将相机和画布关联
camera.attachControl(canvas, true);

上面的代码中,radius被设置为10个单位,表示初始化情况下相机没有进行任何旋转,只是位置设置为离目标观察点10个单位。第5个参数是目标观察点,被设置为(0,0,0)

弧度旋转相机默认可以通过按住CTRL键+鼠标左键来平移,当然你也可以通过在attachControl里设置useCtrlForPanning为false来设置成鼠标右键来平移。

camera.attachControl(canvas, noPreventDefault, useCtrlForPanning);

如果需要,你也可以通过设置来取消平移。

scene.activeCamera.panningSensibility = 0;

panningSensibility = panning移动镜头的意思+Sensibility敏感的意思,也就是是否需要敏感的移动镜头,这里是不需要。


跟随相机(FollowCamera)

顾名思义, FollowCamera跟随相机会跟随它的目标进行移动。跟随相机需要一个网格作为目标,从它当前的位置移动到目标位置,从中观察目标。当目标移动时,跟随摄像机也会移动(想象一下,你在前面走,后面有个人拿着摄像机在拍你)。这个相机能做出很多特效来,如跟随飞机的战斗游戏,Babylon.js提供了很多相机,这也是比Three.js简单的原因之一。

FollowCamera跟随相机构造函数:

FollowCamera(name: string, position: Vector3, scene: Scene, lockedTarget?: Nullable<AbstractMesh>): FollowCamera
  • name: 相机的名字

  • position: 相机的位置

  • scene: 相机属于哪一个场景

  • Optional lockedTarget: 可选参数,定义相机的跟踪的目标物体。

举个例子

// 参数:名字,位置,所属场景    
var camera = new BABYLON.FollowCamera("FollowCam", new BABYLON.Vector3(0, 10, -10), scene);
// 相机与目标的距离
camera.radius = 30;
// 相机超过目标局部坐标中心点的高度
camera.heightOffset = 10;
// 相机在目标局部坐标XY平面内环绕目标的旋转角度
camera.rotationOffset = 0;
// 加速度
camera.cameraAcceleration = 0.005
// 最大速度 
camera.maxCameraSpeed = 10
// 将相机与画布关联
camera.attachControl(canvas, true);
// 注意:这里的babylon.js版本为2.5,后续版本的写法可能会有改变
// 创建目标网格
camera.target = targetMesh;   // 2.4及之前的版本的写法
camera.lockedTarget = targetMesh; // 2.5及之后的版本的写法

仔细看代码中的注释,已经解释得很清楚了。

  • 第2行:当创建摄像机时,设置初始位置,然后用三个参数设置目标位置。

  • 第4行:相机的半径(camera.radius)—— 与目标之间的距离;

  • 第6行:相机的高度偏移量(camera.heightOffset)—— 相机在目标之上的高度;

  • 第10到12行,也许你想知道相机的加速度、最大速度,其实你理解相机不是匀速运动的就可以了。

好了跟随相机就介绍到这里了。难忘的时刻,总是那么有限,我们下节课再见,亲爱的朋友。


小结

本节介绍了集中常用相机,如 ABYLON.UniversalCamera通用相机FollowCamera跟随相机ArcRotateCamera弧度旋转相机等,还有很多相机,我们都没有介绍,这些都需要大家在后面的课程中不断学习,不要心急哦,追女孩子的时候,就是不要心急,先建立良好的印象,学习也一样,先打好基础,然后在一起飞。

今天有点晚了,我们明天再见。