8.图层蒙版和多个相机配合使用

本教程翻译自官方教程Use Layermasks and Multi-Camera Textures,各位也可以进入本站镜像站点查看

本文目录

  1. 使用图层蒙版的多个摄像机的不同网格物体
  2. 灯光
  3. 瞄准镜实例

使用"图层蒙版"的多个摄像机的不同网格物体

    layerMask是分配给每个网格物体和摄像机的数字。它在位级别用于指示灯光和摄像机是否应照亮或显示网格物体。0x0FFFFFFF的默认值将使网格物体被照明,并被任何备用光源和照相机显示。

    该功能主要在多个摄像机同时处于活动状态时使用。如果希望有一个在屏幕上始终可见并且可以拾取的网格物体(例如按钮), 则可以在场景中添加第二个摄像头和光源,以专门显示和照明它。

    您只需要第二台摄像头才能看到该按钮。该按钮也应该仅可见一次。

请注意,默认值layerMask的前4位是0或者off。如果第二台摄像机和按钮都具有layerMask以下四个值之一,则第二台摄像机只会看到该按钮:

  • 0x10000000
  • 0x20000000
  • 0x40000000
  • 0x80000000

    还应注意,任何人都无法看到一个layerMask为0的网格物体。这可能对隐藏事物有好处。

设置多相机:

if (scene.activeCameras.length === 0){
   scene.activeCameras.push(scene.activeCamera);
}
var secondCamera = new Babylon.Camera(...);
secondCamera.layerMask = 0x10000000;
scene.activeCameras.push(secondCamera);

var Button = new BABYLON.Mesh(...);
Button.layerMask = 0x10000000;

灯光

    除非用于第二个摄影机的网格物体的材质纯粹是发光的,否则该按钮仍然会照亮所有其他网格物体,而场景中的其他灯光仍会照亮该按钮。要防止场景灯照亮该按钮,请遍历已存在灯光,并设置excludeWithLayerMask值:

for (var i = scene.lights.length - 1; i >= 0; i--) {
  scene.lights[i].excludeWithLayerMask = 0x10000000;
}

然后使“按钮”亮起:

var light = new BABYLON.Light(...);
light.includeOnlyWithLayerMask = 0x10000000;

最后,如果以后可能会加入更多的灯光,则可以在添加灯光时注册回调:

scene.onNewLightAdded = onNewLight;

可以是:

onNewLight = function(newLight, positionInArray, scene) {
  newLight.excludeWithLayerMask = 0x10000000;
};

瞄准镜实例

    这是使用第二个正交摄影机显示枪瞄准器的简单示例。为了简单起见,使用了发光材料来避免对其进行照明。只需将其复制并粘贴到任何场景中,然后调用它即可。选择的layerMask还允许Babylon的Dialog扩展进行互操作, 也许这些可以结合起来使用测距仪进行平视坦克瞄准。

    商业化质量的实现可能不会使用CreateBox(),因为它会创建无法直接看到的深度面。除非它是平板电脑应用程序,否则还应考虑窗口大小的更改。

function addGunSight(scene) {
  if (scene.activeCameras.length === 0) {
    scene.activeCameras.push(scene.activeCamera);
  }
  var secondCamera = new BABYLON.FreeCamera(
    "GunSightCamera",
    new BABYLON.Vector3(0, 0, -50),
    scene
  );
  secondCamera.mode = BABYLON.Camera.ORTHOGRAPHIC_CAMERA;
  secondCamera.layerMask = 0x20000000;
  scene.activeCameras.push(secondCamera);

  meshes = [];
  var h = 250;
  var w = 250;

  var y = BABYLON.Mesh.CreateBox("y", h * 0.2, scene);
  y.scaling = new BABYLON.Vector3(0.05, 1, 1);
  y.position = new BABYLON.Vector3(0, 0, 0);
  meshes.push(y);

  var x = BABYLON.Mesh.CreateBox("x", h * 0.2, scene);
  x.scaling = new BABYLON.Vector3(1, 0.05, 1);
  x.position = new BABYLON.Vector3(0, 0, 0);
  meshes.push(x);

  var lineTop = BABYLON.Mesh.CreateBox("lineTop", w * 0.8, scene);
  lineTop.scaling = new BABYLON.Vector3(1, 0.005, 1);
  lineTop.position = new BABYLON.Vector3(0, h * 0.5, 0);
  meshes.push(lineTop);

  var lineBottom = BABYLON.Mesh.CreateBox("lineBottom", w * 0.8, scene);
  lineBottom.scaling = new BABYLON.Vector3(1, 0.005, 1);
  lineBottom.position = new BABYLON.Vector3(0, h * -0.5, 0);
  meshes.push(lineBottom);

  var lineLeft = BABYLON.Mesh.CreateBox("lineLeft", h, scene);
  lineLeft.scaling = new BABYLON.Vector3(0.01, 1, 1);
  lineLeft.position = new BABYLON.Vector3(w * -0.4, 0, 0);
  meshes.push(lineLeft);

  var lineRight = BABYLON.Mesh.CreateBox("lineRight", h, scene);
  lineRight.scaling = new BABYLON.Vector3(0.01, 1, 1);
  lineRight.position = new BABYLON.Vector3(w * 0.4, 0, 0);
  meshes.push(lineRight);

  var gunSight = BABYLON.Mesh.MergeMeshes(meshes);
  gunSight.name = "gunSight";
  gunSight.layerMask = 0x20000000;
  gunSight.freezeWorldMatrix();

  var mat = new BABYLON.StandardMaterial("emissive mat", scene);
  mat.checkReadyOnlyOnce = true;
  mat.emissiveColor = new BABYLON.Color3(0, 1, 0);

  gunSight.material = mat;
}

演示实例

贡献者

翻译: Alshat