摄像机
在Babylon.js的众多的可用摄像机中,最常用的两种可能是用于“第一人称”运动的通用相机、轨道相机ArcRotateCamera,以及用于现代虚拟现实体验的WebXRCamera。
为了允许用户输入,摄像机必须被附加在canvas中
camera.attachControl(canvas, true);
其中第二个参数是可选的,默认为false,这将阻止画布事件上的默认操作。设置为true可允许画布默认操作。
注意:
1. 输入设备Gamepads作为控制器
2. 为了触摸控制,需要引入PEP或hand.js
通用相机(Universal Camera)
通用相机是在Babylon.js的2.3版本中引入的,可以被键盘、鼠标、触摸板或游戏板控制,具体取决于所使用的输入设备,无需指定的控制器。这个扩展功能取代了之前的自由相机(Free Camera),触摸相机(Touch Camera)和游戏板相机(Gamepad Camera),但被取代的这些仍然是可用的。
通用相机现在是Babylon.js使用的默认相机,如果你想在场景中使用类似第一人称(FPS)的控制器,它是你的最佳选择。babylonjs.com上的所有demo都使用通用相机。将Xbox控制器插入你的电脑,你就可以使用它浏览大多数演示了。
默认操作为:
键盘-左右箭头键左右移动相机,上下箭头键前后移动相机;
鼠标-以相机为原点绕轴旋转相机;
触摸-左右滑动可左右移动相机,上下滑动可前后移动相机;
游戏板-对应于设备的按键
可选动作:
鼠标滚轮-鼠标上的滚轮或触摸板上的滚动动作。
案例:通用相机上添加鼠标滚轮
注意:
在Playground中使用键盘按键的话,需要在渲染区域内部单击获取焦点。
构件一个通用相机
// Parameters : name, position, scene
const camera = new BABYLON.UniversalCamera("UniversalCamera", new BABYLON.Vector3(0, 0, -10), scene);
// Targets the camera to a particular position. In this case the scene origin
camera.setTarget(BABYLON.Vector3.Zero());
// Attach the camera to the canvas
camera.attachControl(canvas, true);
弧形旋转摄像机(Arc Rotate Camera)
该相机总是指向给定的目标位置,并且可以以目标为旋转中心围绕该目标旋转。它可以用光标和鼠标控制,也可以用触摸事件控制。
把这个相机想象成一个绕其目标位置运行的相机,或者更具想象力地想象成一颗绕地球运行的卫星。它相对于目标(“地球”)的位置可以通过三个参数设置:
- alpha(纵向旋转,以弧度为单位)
- beta(纬度旋转,以弧度为单位)
- radius(距目标的距离)
插图如下:
由于技术原因,将beta设置为0或PI可能会导致问题,因此在这种情况下,beta会偏移0.1弧度(约0.6度)
beta沿顺时针方向增加,而alpha沿逆时针方向增加。
摄影机的位置也可以通过矢量进行设置,该矢量将覆盖alpha、beta和radius的所有当前设置的值。这可能比计算所需角度容易得多。
无论使用键盘、鼠标还是触摸滑动,左/右方向都会更改alpha,上/下方向会更改beta。
以下可选的的属性也很方便:
- zoomToMouseLocation - 如果设置为true,将导致鼠标滚轮以当前鼠标位置为中心放大或缩小,而不是以固定的相机目标位置为中心。这样可以轻松地探索大型场景的各个角落。设置此项意味着鼠标滚轮将在鼠标滚轮缩放期间更改相机的目标位置。当设置为true时,使用鼠标滚轮的缩放操作同时进行缩放和少量平移
- wheelDeltaPercentage - 如果设置为非零值,将导致缩放量设置为相机半径的百分比。这意味着随着距离目标对象越来越近,缩放速度会减慢,这很好,因为这意味着在近距离探索对象时,可以更精确地放置相机。
构件弧形旋转摄像机
// Parameters: name, alpha, beta, radius, target position, scene
const camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, new BABYLON.Vector3(0, 0, 0), scene);
// Positions the camera overwriting alpha, beta, radius
camera.setPosition(new BABYLON.Vector3(0, 0, 20));
// This attaches the camera to the canvas
camera.attachControl(canvas, true);
代码示例Playground
默认情况下,也可以使用Ctrl+鼠标左键使用ArcRotateCamera进行平移。您可以使用鼠标右键,方法是在attachControl调用中将useCtrlForPanning设置为false:
camera.attachControl(canvas, noPreventDefault, useCtrlForPanning);
如果需要,还可以通过设置完全禁用平移:
camera.panningSensibility = 0;
以下是演示其中一些内容的演示,以及ArcRotateCamera的其他功能:
地址
跟随相机(FollowCamera)
跟随相机完全和他表面的意义一致。将某个三维网格Mesh作为目标,无论目标从当前任何位置移动到目标任何位置,只要目标移动,跟随相机会随之而动。
跟随相机创建后的厨师位置由创建时的3个参数决定:
- radius: 距离目标的长度
- heightOffset:距离目标上方的高度
- rotationOffset:x、y平面上的角度
摄影机移动到目标位置的速度是通过其加速度(cameraAcceleration)设置的,最高可达最大速度(maxCameraSpeed)。
创建跟随相机的代码:
// Parameters: name, position, scene
const camera = new BABYLON.FollowCamera("FollowCam", new BABYLON.Vector3(0, 10, -10), scene);
// The goal distance of camera from target
camera.radius = 30;
// The goal height of camera above local origin (centre) of target
camera.heightOffset = 10;
// The goal rotation of camera around local origin (centre) of target in x y plane
camera.rotationOffset = 0;
// Acceleration of camera in moving from current to goal position
camera.cameraAcceleration = 0.005;
// The speed at which acceleration is halted
camera.maxCameraSpeed = 10;
// This attaches the camera to the canvas
camera.attachControl(canvas, true);
// NOTE:: SET CAMERA TARGET AFTER THE TARGET'S CREATION AND NOTE CHANGE FROM BABYLONJS V 2.5
// targetMesh created here.
camera.target = targetMesh; // version 2.4 and earlier
camera.lockedTarget = targetMesh; //version 2.5 onwards
示例
立体相机(AnaglyphCameras)
AnaglyphUniversalCamera和AnaglyprAcRotateCamera扩展了通用和弧形旋转相机的使用范围,可用于红色和青色3D眼镜。它们使用后处理(Post-processing)过滤技术。
// Parameters : name, position, eyeSpace, scene
const camera = new BABYLON.AnaglyphUniversalCamera("af_cam", new BABYLON.Vector3(0, 1, -15), 0.033, scene);
// Parameters : name, alpha, beta, radius, target, eyeSpace, scene
const camera = new BABYLON.AnaglyphArcRotateCamera("aar_cam", -Math.PI / 2, Math.PI / 4, 20, BABYLON.Vector3.Zero(), 0.033, scene);
eyeSpace参数设置左眼视图和右眼视图之间的偏移量。一旦你戴上3D眼镜,你可能想尝试一下这个float值。
你可以通过访问维基百科的页面来了解所有关于红蓝立体照片(anaglyphs )的信息。
面向设备相机(Device Orient Camera)
DeviceOrientationCamera专为应对设备响应事件而设计,例如现代移动设备向前、向后、向左或向右倾斜。
// Parameters : name, position, scene
const camera = new BABYLON.DeviceOrientationCamera("DevOr_camera", new BABYLON.Vector3(0, 0, 0), scene);
// Targets the camera to a particular position
camera.setTarget(new BABYLON.Vector3(0, 0, -10));
// Sets the sensitivity of the camera to movement and rotation
camera.angularSensibility = 10;
camera.moveSensibility = 10;
// Attach the camera to the canvas
camera.attachControl(canvas, true);
虚拟摇杆相机(Virtual Joysticks Camera)
VirtualJoysticksCamera是专门为应对虚拟游戏杆事件而设计的。虚拟操纵杆是屏幕上的2D图形,用于控制相机或其他场景项目。
注意:此相机需要第三方文件hand.js。
完整代码示例
document.addEventListener("DOMContentLoaded", startGame, false);
function startGame() {
if (BABYLON.Engine.isSupported()) {
const canvas = document.getElementById("renderCanvas");
const engine = new BABYLON.Engine(canvas, true);
BABYLON.SceneLoader.Load("Espilit/", "Espilit.babylon", engine, function (newScene) {
const 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.
}),
}
}
如果你切换回另一台相机,请不要忘记先调用dispose方法。VirtualJoystick会在3D WebGL canvas上创建一个2D canvas,以绘制带有青色和黄色圆圈的游戏杆。如果忘记调用dispose方法,2D画布将保留并继续处理触摸事件。
VR设备摄像机(VR Device Orientation Cameras)
VRDeviceOrientationFreeCamera、VRDeviceOriginationArcRotateCamera和VRDeviceOrientionGamepadCamera是一组较新的相机,它们扩展了上面的相机,以处理VR设备的设备方向。
// Parameters: name, position, scene, compensateDistortion, vrCameraMetrics
const camera = new BABYLON.VRDeviceOrientationFreeCamera("Camera", new BABYLON.Vector3(-6.7, 1.2, -1.3), scene);
// Parameters: name, alpha, beta, radius, target, scene, compensateDistortion, vrCameraMetrics
const 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
const camera = new BABYLON.VRDeviceOrientationGamepadCamera("Camera", new BABYLON.Vector3(-10, 5, 14));
代码示例