相机

相机

一月 16, 2024

1、相机

通用相机UniversalCamera,模仿第一人称的移动视角;

弧形旋转相机ArcRotateCamera,它是一种轨道相机,可以控制远近和角度

如果要让用户对相机进行控制,就需要把输入事件绑定到初始化的canvas对象上

1
camera.attachControl(canvas, true);

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

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

2、构建通用相机

// 参数顺序 : name相机名称, position相机放置的位置, scene场景实例

1
var camera = new BABYLON.UniversalCamera("UniversalCamera", new BABYLON.Vector3(0, 0, -10), scene);

//相机观察的目标,在这里表示:相机放在(0,0,-10),镜头对准观察 (0,0,0)

1
camera.setTarget(BABYLON.Vector3.Zero());

// 让相机响应用户操作

1
camera.attachControl(canvas, true);

3、弧形旋转相机Arc Rotate Camera

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

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

// 参数: alpha, beta, radius, 目标位置position, scene场景实例

1
2
var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, new BABYLON.Vector3(0, 0, 0), scene);
camera.attachControl(canvas, true);

// 设置后会覆盖alpha, beta, radius

1
camera.setPosition(new BABYLON.Vector3(0, 0, 20));

// 让相机响应用户操作

跟随相机FollowCamera

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

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

camera.radius - 相机距离目标的距离

camera.heightOffset - 相机朝目标上方的偏移

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

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

// 参数: name相机名称, position相机位置, scene场景实例

1
var camera = new BABYLON.FollowCamera("FollowCam", new BABYLON.Vector3(0, 10, -10), scene);

// 相机距离目标的距离

1
camera.radius = 30;

// 相机朝目标上方的偏移

1
camera.heightOffset = 10;

// 相机与目标在水平面的角度偏移,默认相机和目标在同一水平面

1
camera.rotationOffset = 0;

// 相机靠近目标位置的加速度

1
camera.cameraAcceleration = 0.005

// 相机达到的最大速度

1
camera.maxCameraSpeed = 10

// 让相机响应用户操作

1
camera.attachControl(canvas, true);

// 注意:设置相机目标,注意BabylonJS V 2.5的变化

// targetMesh为目标物体

1
2
3
camera.target = targetMesh; // babylon 2.4 版本以前

camera.lockedTarget = targetMesh; //babylon 2.5 版本以后

立体相机AnaglyphCameras

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

构建立体通用相机

// 参数 : name, position, eyeSpace, scene

1
var camera = new BABYLON.AnaglyphUniversalCamera("af\_cam", new BABYLON.Vector3(0, 1, -15), 0.033, scene);

构建立体弧形旋转相机

// 参数 : name, alpha, beta, radius, target, eyeSpace, scene

1
var camera = new BABYLON.AnaglyphArcRotateCamera("aar\_cam", -Math.PI/2, Math.PI/4, 20, new BABYLON.Vector3.Zero(), 0.033, scene);

设备方向相机Device Orientation Camera

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

// 参数 : name, position, scene

1
var camera = new BABYLON.DeviceOrientationCamera("DevOr\_camera", new BABYLON.Vector3(0, 0, 0), scene);

// 设置相机的观察目标位置

1
camera.setTarget(new BABYLON.Vector3(0, 0, -10));

// 设置相机响应移动和旋转的敏感度

1
2
3
camera.angularSensibility = 10;

camera.moveSensibility = 10;

// 让相机响应用户操作

1
camera.attachControl(canvas, true);

虚拟摇杆相机

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
pan\>

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.

}),

}

}