8. 相机-找一个合适的观察视角

本教程翻译自官方教程Cameras ,各位也可以进入本站镜像站点查看

本文目录

  1. 相机Cameras
    1. 通用相机Universal Camera
      1. 构建通用相机
    2. 弧形旋转相机Arc Rotate Camera
      1. 构建弧形旋转相机
    3. 跟随相机FollowCamera
      1. 构建跟随相机
    4. 立体相机AnaglyphCameras
      1. 构建立体通用相机
      2. 构建立体弧形旋转相机
    5. 设备方向相机Device Orientation Camera
      1. 构建设备方向相机
    6. 虚拟摇杆相机
      1. 依赖
      2. 概念阅读
      3. 视频教程
      4. 完整示例
    7. 虚拟现实设备方向相机VR Device Orientation Cameras
      1. 构建虚拟现实设备方向自由相机
      2. 构建虚拟现实设备方向弧形旋转相机
      3. 构建虚拟现实设备方向游戏手柄相机
    8. WebVR自由相机
    9. 飞行相机
      1. 构建飞行相机
    10. 自定义输入
    11. 下一步
  2. 延伸阅读
  3. 贡献者

相机Cameras

    在Babylon.js提供的许多相机中,常用的目前是2个:通用相机UniversalCamera,模仿第一人称的移动视角;弧形旋转相机ArcRotateCamera,它是一种轨道相机,可以控制远近和角度。随着WebVR的来临,可能常用的相机会增加。
    如果要让用户对相机进行控制,就需要把输入事件绑定到初始化的canvas对象上,具体代码如下:

camera.attachControl(canvas, true);

    第二个参数是可选的,默认false。当false的时候,canvas的默认行为被禁止,也就是调用了event.preventDefault(),如果为true,canvas保留默认行为。

注意
游戏手柄也可以作为一个控制器来控制相机移动
触摸事件需要引入PEP或者hand.js

通用相机Universal Camera

    通用相机最早在Babylon.js2.3版本的时候被引入,可以根据输入设备响应键盘、鼠标、触摸和游戏手柄的控制操作,不需要再特别指定控制器。通用相机扩展并且替代了自由相机Free Camera、触摸相机Touch Camera和游戏手柄相机Gamepad Camera,但是考虑到兼容性问题,以上三种相机任然可以使用。

    在使用函数快速创建整个场景时,通用相机会作为默认相机添加到场景中,假如想像第一人称射击游戏那样来控制我们的场景视角,通用相机也是最好的选择。babylonjs首页的所有案例演示都使用了通用相机。就算是在电脑上使用Xbox的游戏手柄,首页中的大多数案例也能够由手柄操作来查看效果。

    通用相机的默认控制:

  • 键盘 - 左右方向键能够左右移动相机的视角,而上下方向键能够把相机拉近或推远。
  • 鼠标 - 按住鼠标左键或右键进行拖动,可以控制相机的视角。
  • 触摸屏 - 左右滑动可左右移动相机,上下滑动可拉近或推远;
  • 游戏手柄 - 和设备相关,常规手柄就是上下左右键控制。

注意
在Playground中使用按键需要单击canvas画布并使其具有焦点。

构建通用相机

// 参数顺序 : name相机名称, position相机放置的位置, scene场景实例
var camera = new BABYLON.UniversalCamera("UniversalCamera", new BABYLON.Vector3(0, 0, -10), scene);

//相机观察的目标,在这里表示:相机放在(0,0,-10),镜头对准观察 (0,0,0)
camera.setTarget(BABYLON.Vector3.Zero());

// 让相机响应用户操作
camera.attachControl(canvas, true);

Playground 通用相机示例

弧形旋转相机Arc Rotate Camera

    弧形旋转相机总是指向一个给定的目标位置,而且能够以此目标位置作为中心进行360°旋转。它的操作体验和观察角度比通过相机更灵活,同样能够响应鼠标、键盘、游戏手柄和触摸事件。

    可将弧形旋转相机视为一个围绕其目标位置进行观察的摄像机,或者想象一下,它更像是一个环绕地球轨道运行的间谍卫星。相对于目标(地球)位置,相机自身的位置可以设置三个参数:即纵向旋转的alpha(弧度),横向旋转的beta(弧度)和代表距目标位置距离的半径radius。 这是一个实例:

1-camalphabeta

    由于技术原因,将beta设置为0或者PI(180°)会引起问题,在这种情况下可以将beta在0或PI的基础上偏移0.1弧度(0.6°)。

    增加alpha和beta的值,相机会沿顺时针方向变化。

    也可以使用setPosition直接设置弧度旋转相机的向量位置,这样的情况下,alpha、beta、radius的值将会被覆盖。这比计算所需角度要容易,但是理解起来比较抽象。

    使用键盘左右键、鼠标或触摸屏向左或向右滑动可以更改Alpha值,而上下方向可以更改Beta值。

构建弧形旋转相机

// 参数: alpha, beta, radius, 目标位置position, scene场景实例
    var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, new BABYLON.Vector3(0, 0, 0), scene);

// 设置后会覆盖alpha, beta, radius
    camera.setPosition(new BABYLON.Vector3(0, 0, 20));

// 让相机响应用户操作
    camera.attachControl(canvas, true);

Playground 弧形旋转相机示例

可以使用 Ctrl + 鼠标左键鼠标右键 让弧形旋转相机进行平移,也就是修改相机观察的目标位置,如果要禁用 Ctrl + 鼠标左键 平移,可以在attachControl中将useCtrlForPanning设置为false,代码如下:

camera.attachControl(canvas, noPreventDefault, useCtrlForPanning);

如果有需要,也可以完全取消平移操作:

//这个值用来控制平移的灵敏度,为0就是完全不响应平移
scene.activeCamera.panningSensibility = 0;

跟随相机FollowCamera

    跟随相机可以一直守望着ta。只要给它一个物体作为跟随目标,跟随相机能够从任何位置移动过来,一直紧盯目标物体,一旦物体移动了,跟随相机也会跟着移动。

    创建跟随相机时需要设置它的初始位置,然后目标位置根据以下三个参数进行控制:

  • camera.radius - 相机距离目标的距离
  • camera.heightOffset - 相机朝目标上方的偏移
  • camera.rotationOffset - 相机与目标在水平面的角度偏移,默认相机和目标在同一水平面:rotationOffset增加则相机会朝着顺时针方向围绕物体水平转动。

    通过设置camera.cameraAcceleration加速度和camera.maxCameraSpeed最大速度,可以控制相机移动到目标位置的动态效果。

构建跟随相机

// 参数: name相机名称, position相机位置, scene场景实例
var camera = new BABYLON.FollowCamera("FollowCam", new BABYLON.Vector3(0, 10, -10), scene);

// 相机距离目标的距离
camera.radius = 30;

// 相机朝目标上方的偏移
camera.heightOffset = 10;

// 相机与目标在水平面的角度偏移,默认相机和目标在同一水平面
camera.rotationOffset = 0;

// 相机靠近目标位置的加速度
camera.cameraAcceleration = 0.005

// 相机达到的最大速度
camera.maxCameraSpeed = 10

// 让相机响应用户操作
camera.attachControl(canvas, true);

// 注意:设置相机目标,注意BabylonJS V 2.5的变化
// targetMesh为目标物体
camera.target = targetMesh;   // babylon 2.4 版本以前
camera.lockedTarget = targetMesh; //babylon 2.5 版本以后

Playground 跟着目标物体移动的跟随相机示例

立体相机AnaglyphCameras

    立体相机由通用相机和弧形旋转相机扩展而来,专门用来给3D眼镜(红色和青色镜片的那种眼镜)使用,它们用到了后期滤波器技术。

构建立体通用相机

// 参数 : name, position, eyeSpace, scene
var camera = new BABYLON.AnaglyphUniversalCamera("af_cam", new BABYLON.Vector3(0, 1, -15), 0.033, scene);

构建立体弧形旋转相机

// 参数 : name, alpha, beta, radius, target, eyeSpace, scene
var camera = new BABYLON.AnaglyphArcRotateCamera("aar_cam", -Math.PI/2, Math.PI/4, 20, new BABYLON.Vector3.Zero(), 0.033, scene);

    eyeSpace参数设置左眼视图和右眼视图之间的偏移量。 戴好3D眼镜后,可以尝试调整这个数值,取值为float。

可以通过访问Wikipedia全面了解立体技术

设备方向相机Device Orientation Camera

    这是专门设计用于对手持设备方向事件做出响应的相机,例如智能手机向前或向后,向左或向右倾斜,陀螺仪会改变方向,最后让屏幕显示横屏或者竖屏。

构建设备方向相机

// 参数 : name, position, scene
var camera = new BABYLON.DeviceOrientationCamera("DevOr_camera", new BABYLON.Vector3(0, 0, 0), scene);

// 设置相机的观察目标位置
camera.setTarget(new BABYLON.Vector3(0, 0, -10));

// 设置相机响应移动和旋转的敏感度
camera.angularSensibility = 10;
camera.moveSensibility = 10;

// 让相机响应用户操作
camera.attachControl(canvas, true);

Playground 设备方向相机示例

需要手机来看这个示例,把屏幕方向锁定设置关掉哦

虚拟摇杆相机

    这是特别为手持设备设计的,可以有一个虚拟摇杆显示在屏幕上,就像在手机上吃鸡的虚拟方向操纵杆那样。虚拟操纵杆是显示屏幕上的二维图形,用于控制相机的观察角度以及其他情况。

依赖

由于为触摸屏设备设计,所以需要依赖第三方插件hand.js

概念阅读

看看大牛的博客,了解一下基本概念

视频教程

演示视频也来一个

2-VJCBabylon

完整示例

document.addEventListener("DOMContentLoaded", startGame, false);
function startGame() {
  if (BABYLON.Engine.isSupported()) {
    var canvas = document.getElementById("renderCanvas");
    var engine = new BABYLON.Engine(canvas, true);

    BABYLON.SceneLoader.Load("Espilit/", "Espilit.babylon", engine, function (newScene) {

      var VJC = new BABYLON.VirtualJoysticksCamera("VJC", newScene.activeCamera.position, newScene);
      VJC.rotation = newScene.activeCamera.rotation;
      VJC.checkCollisions = newScene.activeCamera.checkCollisions;
      VJC.applyGravity = newScene.activeCamera.applyGravity;

      // Wait for textures and shaders to be ready
      newScene.executeWhenReady(function () {
        newScene.activeCamera = VJC;
        // Attach camera to canvas inputs
        newScene.activeCamera.attachControl(canvas);
        // Once the scene is loaded, just register a render loop to render it
        engine.runRenderLoop(function () {
          newScene.render();
        }),
      }),
    }, function (progress) {
    // To do: give progress feedback to user.
    }),
  }
}

虚拟现实设备方向相机VR Device Orientation Cameras

    Playground 虚拟现实设备方向相机示例需要使用VR设备才能看到完整的效果。

构建虚拟现实设备方向自由相机

//参数: name, position, scene, compensateDistortion, vrCameraMetrics
var camera = new BABYLON.VRDeviceOrientationFreeCamera ("Camera", new BABYLON.Vector3 (-6.7, 1.2, -1.3), scene);

构建虚拟现实设备方向弧形旋转相机

//Parameters: name, alpha, beta, radius, target, scene, compensateDistortion, vrCameraMetrics
var camera = new BABYLON.VRDeviceOrientationArcRotateCamera ("Camera", Math.PI/2, Math.PI/4, 25, new BABYLON.Vector3 (0, 0, 0), scene);

构建虚拟现实设备方向游戏手柄相机

//Parameters: name, position, scene, compensateDistortion, vrCameraMetrics
var camera = new BABYLON.VRDeviceOrientationGamepadCamera("Camera", new BABYLON.Vector3 (-10, 5, 14));

WebVR自由相机

    根据WebVR标准制作的虚拟现实相机,建议用这个替代之前用到的虚拟现实设备方向相机。创建方式如下:

// Parameters : name, position, scene, webVROptions
    var camera = new BABYLON.WebVRFreeCamera("WVR", new BABYLON.Vector3(0, 1, -15), scene);

    这里只是简单介绍一下,其实WebVR非常重要,所以有自己的教程进行专门介绍。WebVR相机的使用

飞行相机FlyCamera

    该相机模仿3D空间中的自由飞行,可以想象为“3D空间飞行的幽灵战机”,飞行相机有逐步校正侧倾的设置,以及模拟倾斜转弯的设置,可以用到第一人称飞行体验游戏中。

    它响应以下操作:

  • 键盘 - A和D键可左右移动相机。 使用W和S键向前和向后移动。 E和Q键可上下移动。

  • 鼠标 - 以摄像机为原点,按照纵向和横向(X, Y)轴旋转摄像机。 按住鼠标右键,以摄像机为原点,使摄像机绕着Z轴旋转。

构建飞行相机

// 参数: name, position, scene
var camera = new BABYLON.FlyCamera("FlyCamera", new BABYLON.Vector3(0, 5, -10), scene);

//像飞机一样盘旋,具有更快的侧倾校正和倾斜转弯。

//默认值为100。数字越大,校正速度越慢。
camera.rollCorrect = 10;

// 默认是 false.
camera.bankedTurn = true;

// 弧度默认为90°,倾斜多少度就让相机侧倾。
camera.bankedTurnLimit = Math.PI / 2;

//多少偏航(转弯)会影响滚动(倾斜转弯)。
//小于1会减少侧倾,大于1会增加侧倾。
camera.bankedTurnMultiplier = 1;

// This attaches the camera to the canvas
camera.attachControl(canvas, true);

自定义输入

    相机根据用户输入来交互的移动位置,如果满意Babylon.js提供的以上相机预设,那就愉快的使用下去,如果觉得不满意,请往下看。

    如果你想基于现有的相机预设来增减用户输入行为,可以对现有相机进行自定义,或者全新定义一个相机的用户输入行为也是可以的。以上的相机都具备一个输入管理器,适应一些高级的应用场景。请阅读自定义相机输入来了解更多这方面的信息。

下一步

    现在你已经学习了相机的使用,并且还接触了通用相机和弧度旋转相机的高级用法。而且还能控制查看自己场景的角度,并选择一个输入设备来与相机进行交互,移动、旋转相机也已经可以做到。接下来为了给场景带来更加逼真的效果,我们将在下一章学习如何管理灯光,请移步灯光-学会为物体打光。一会见哦!

延伸阅读

相机概述

贡献者

翻译/校对: Cow&Sheep
Playground: 天才
技术支持: Dushusir github

参与贡献? 联系alexads@foxmail.com