BabylonJS 6.0文档 Deep Dive 摄像机(一):摄像机介绍

摄像机

在Babylon.js的众多的可用摄像机中,最常用的两种可能是用于“第一人称”运动的通用相机、轨道相机ArcRotateCamera,以及用于现代虚拟现实体验的WebXRCamera。

为了允许用户输入,摄像机必须被附加在canvas中

camera.attachControl(canvas, true);

其中第二个参数是可选的,默认为false,这将阻止画布事件上的默认操作。设置为true可允许画布默认操作。

注意:

1. 输入设备Gamepads作为控制器

2. 为了触摸控制,需要引入PEPhand.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));

代码示例

WebVR自由摄像机(Web VR Free Camera)

注意:WebVR已弃用!请改用WebXR

WebXR摄像机会在另外的章节介绍

自由摄像机(FreeCamera)

注意:新版本用通用相机替代之。

相机的平面剖切与无限透视

Babylon.js中的相机具有平面剖切的功能,用于指定将渲染的场景中的视觉范围。任何超出该范围的内容都不会被渲染。例如,将相机的maxZ设置为100,如下所示:

camera.maxZ = 100;

摄影机将不会从渲染任何超过100单位距离的内容。近剪裁平面也是如此。例如,将minZ设置为10,如下所示:

camera.minZ = 10;

将不会从相机渲染任何近于10单位距离以内的内容。

在某些情况下,您可能不希望平面剖切的渲染。您可能希望场景有效地渲染到无穷大。这可以通过如下方式将maxZ设置为0来完成:

camera.maxZ = 0;

只是一个友好的警告,将场景渲染到无穷大会降低深度精度,所以要小心使用!

自定义输入

摄像机依靠用户输入来移动摄像机。如果你对Babylon.js给你的相机预设感到满意,那就保持下去。

如果希望根据用户偏好更改用户输入,更改已存在的某个预设值,或使用自定义输入机制。这些相机有一个输入管理器,专为这些高级场景设计。阅读自定义相机输入,了解有关调整相机输入的更多信息。

校正透视投影(Correcting perspective projection)

直译比较绕,类似于这么个意思,在建筑场景下,近大远小会造成一些问题,需要使用applyVerticalCorrection的放大校正之。

如果您正在制作建筑渲染方面的程序,有可能遇到需要补偿垂直线的透视倾斜。考虑一下这种情况:您正在从人眼的角度渲染一座高层建筑。自然,垂直线会汇聚到一个消失点,就像在这个案例上一样:

虽然这是符合现实情况的,但它可能在视觉上看不出来。如果这些线之间的角度保持很低,则可以考虑使用camera.applyVerticalCorrection()校正。此方法将自动计算当前摄像机俯仰角的垂直校正:

如果你想进一步控制其他相机投影平面的倾斜,你可以使用camera.projectionPlaneTtilt属性。有关更多信息,请参阅此论坛帖子

  • 21
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
DeepDive是一种基于机器学习的知识抽取系统,可以帮助我们从海量的非结构化数据中提取出有用的知识。 举个例子来说明DeepDive的知识抽取实例。假设我们拥有一个包含大量餐馆评论的文本数据库,我们希望从中提取出关于不同餐馆的菜品口味的知识。 首先,我们需要为DeepDive提供一些训练数据,这些数据包括标注好的句子,其中指出了每个词语是否与菜品的味道相关。接着,DeepDive使用这些训练数据进行机器学习,以便能够识别与菜品味道相关的词语。 一旦训练完成,我们就可以使用DeepDive来处理整个餐馆评论数据库。DeepDive将会对每个句子中的词语进行标注,以确定其与菜品味道的相关性。例如,DeepDive可能会识别出句子中的"好吃"、"美味"、"难吃"等词语与菜品味道相关。然后,DeepDive可以根据这些标注将句子分类为积极评价或消极评价。 通过合并和整理这些标注好的句子,我们可以得到一个包含丰富知识的数据库。这个数据库可以告诉我们哪些餐馆的菜品被认为是好吃的,哪些被认为是难吃的。我们可以利用这些知识来做更深入的分析,例如找到味道最好的菜,或者预测一个餐馆的成功度。 总之,DeepDive的知识抽取实例能够帮助我们从非结构化的数据中提取出有用的知识,帮助我们做出更好的决策和发现更多的见解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值