1. 程式人生 > >【Babylonjs】相機

【Babylonjs】相機

六、相機

    在BabylonJs裡的眾多相機中使用最多的有兩種——通用相機(the Universal Camera)一般用於第一人稱的活動,弧形旋轉相機( the Arc Rotate Camera )是一種軌道相機。隨著WebVR的到來,它們可能發生改變。

    對於使用者使用的所有相機都需要將其與畫布關聯起來。

camera.attachControl(canvas, true);

    第二個引數是預設可選的,預設值為false。當引數為false時,可以阻止畫布事件上的預設操作;而當其設定為true時,則允許畫布預設操作。

    另外,遊戲手柄可以使用一個控制器,當需要使用觸控控制的時候需要載入PEP或者hand.js。

通用相機(Universal Camera)

    這裡介紹的是2.3版本Babylon.js中的相機,可以通過使用鍵盤、滑鼠、觸控、遊戲手柄輸入控制,無需指定控制器。它延伸和替代了仍然可以使用的自由相機(Free Camera)、觸控相機(Touch Camera)和遊戲手柄相機(Gamepad Camera)。

    現在通用相機在沒有特殊需求的情況下被BabylonJs用做預設相機。同時如果你想要在你的場景裡使用第一人稱視角,它也是你最好的選擇。

    在官網(babylonjs.com)裡所有的案例演示都基於這個特徵,如果把Xbox控制器插到你的電腦上,你仍然可以使用它瀏覽大部分的案例演示。

    預設操作:

         鍵盤——左右箭頭(方向鍵 ← →)控制相機左右移動,向上和向下箭頭(方向鍵 ↑ ↓ )控制相機向前和向後移動;
        滑鼠——以攝像機為原點旋轉攝像機;
        觸控——左右滑動,左右移動相機,上下滑動,前後移動;
        手柄——裝置上對應的按鍵控制方向和移動。

    提示:你需要點選渲染的場景才能使控制生效。

通用相機的構造

//引數:名字,位置,所屬場景
var camera = new BABYLON.UniversalCamera("UniversalCamera", new BABYLON.Vector3(0, 0, -10), scene);
//給相機的目標設定特定的位置(相機總是朝向它的目標),在這個例子中設定為場景的原點
camera.setTarget(BABYLON.Vector3.Zero());
//將相機和畫布關聯
camera.attachControl(canvas, true);

嘗試一下

弧度旋轉相機(Arc Rotate Camera)

     這個相機總是指向一個給定的目標位置,並且可以圍繞目標旋轉,目標是旋轉的中心。它可以用滑鼠來控制,也可以用觸控事件來控制。
    想象一下,這個相機其實就是一個間諜衛星繞地球旋轉,可以將期各個方位的細節展示出來。其相對於目標的位置(地球)可以設定三個引數,α(弧度)的縱向旋轉,β(弧度)橫向旋轉以及與目標的距離。

    例子:

arc rotate camera

    測試設定為0或PI時,由於技術上的原因,在這種情況下,β是0.1弧度的偏移量(約0.6度)。

    α和β都以順時針方向增加。

    相機的位置也可以通過設定一個向量來覆蓋α,β和半徑。這比計算所需的角度要容易得多。

    無論是使用鍵盤、滑鼠或觸控滑動的左右方向和上下方向都能改變α和β。

弧度旋轉相機的構造

// 引數:縱向旋轉角度alpha、橫向旋轉角度beta、半徑、目標位置、所屬場景
var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, new BABYLON.Vector3(0, 0, 0), scene);
// 這是相機的位置,覆蓋相機的alpha、beta、半徑值
camera.setPosition(new BABYLON.Vector3(0, 0, 20));
// 將相機和畫布關聯
camera.attachControl(canvas, true);

嘗試一下

    弧度旋轉相機預設可以通過按住CTRL鍵+滑鼠左鍵來平移,當然你也可以通過在attachControl裡設定useCtrlForPanning為false來設定成滑鼠右鍵來平移。

camera.attachControl(canvas, noPreventDefault, useCtrlForPanning);

    如果需要,你也可以通過設定來取消平移。

scene.activeCamera.panningSensibility = 0;

跟隨相機(FollowCamera)

    顧名思義,跟隨相機會跟隨它的目標進行移動。跟隨相機需要一個網格作為目標,從它當前的位置移動到目標位置,從中觀察目標。當目標移動時,跟隨攝像機也會移動(想象一下,你在前面走,後面有個人拿著攝像機在拍你)。

    當建立攝像機時,設定初始位置,然後用三個引數設定目標位置:

        相機的半徑(camera.radius)—— 與目標之間的距離;

        相機的高度偏移量(camera.heightOffset)—— 相機在目標之上的高度;

        相機在XY平面上環繞目標的角度。

    相機移動的速度取決於設定的加速度(camera.cameraAcceleration)及最大速度(camera.maxCameraSpeed)。

跟隨相機的構造

// 引數:名字,位置,所屬場景    
var camera = new BABYLON.FollowCamera("FollowCam", new BABYLON.Vector3(0, 10, -10), scene);
// 相機與目標的距離
camera.radius = 30;
// 相機超過目標區域性座標中心點的高度
camera.heightOffset = 10;
// 相機在目標區域性座標XY平面內環繞目標的旋轉角度
camera.rotationOffset = 0;
// 加速度
camera.cameraAcceleration = 0.005
// 最大速度 
camera.maxCameraSpeed = 10
// 將相機與畫布關聯
camera.attachControl(canvas, true);
// 注意:這裡的babylon.js版本為2.5,後續版本的寫法可能會有改變
// 建立目標網格
camera.target = targetMesh;   // 2.4及之前的版本的寫法
camera.lockedTarget = targetMesh; // 2.5及之後的版本的寫法

嘗試一下

立體浮雕相機(AnaglyphCameras)

    這些擴充套件了通用相機和弧度旋轉相機的使用,在它們使用後進行過濾技術處理,用於紅色和青色3D眼鏡。

通用立體浮雕相機的構造

// 引數:名字,位置,視野空間,所屬場景
var camera = new BABYLON.AnaglyphUniversalCamera("af_cam", new BABYLON.Vector3(0, 1, -15), 0.033, scene);

弧度旋轉立體浮雕相機的構造

// 引數:名字,縱向旋轉角度alpha,橫向旋轉角度beta,半徑,目標,視野空間,所屬場景
var camera = new BABYLON.AnaglyphArcRotateCamera("aar_cam", -Math.PI/2, Math.PI/4, 20, new BABYLON.Vector3.Zero(), 0.033, scene);

    引數視野空間(eyespace)指的是左眼和右眼檢視之間的偏移量,一旦你戴上3D眼鏡,你可能想試試這個浮點值。更多關於

裝置定位相機(Device Orientation Camera)

    這是一種專門針對裝置定位事件的相機,例如現代的移動裝置向前傾斜或向後傾斜和向左或向右移動。

裝置定位相機的構造

// 引數:名字,位置,所屬場景    
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);

嘗試一下

虛擬搖桿相機(Virtual Joysticks Camera)

    這是專門用來對虛擬搖桿事件做出反應的。虛擬搖桿是螢幕上的二維圖形,用於控制攝像機或其他現場物品(王者榮耀用來控制行走的左下角那個圈)。

    需要載入hand.js;

完整示例

    這是一個完整的示例,裝載了Espilit演示和切換到一個虛擬搖桿攝像機相機進行控制:

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;      
         // 等待紋理和著色器完成
         newScene.executeWhenReady(function () {
              newScene.activeCamera = VJC;        
              // 將相機和畫布關聯
              newScene.activeCamera.attachControl(canvas);        
              // 場景載入完成,迴圈渲染場景
              engine.runRenderLoop(function () {
                newScene.render();
              }),
            }),
    }, function(progress){    
        // 反饋
    }),
  }
}

    如果你切換到另一個相機,別忘了先使用dispose()功能。virtualjoysticks在3D WebGL畫布上繪製了的二維畫布為青色和黃色的圓圈拉操縱桿。如果你忘記使用dispose()功能,2D畫面將依然存在,並將繼續使用觸控事件的輸入。

VR虛擬現實裝置定位相機(VR Device Orientation Cameras)

    一種新的相機。

 嘗試一下

VR裝置定位自由相機的構造(Constructing the VR Device Orientation Free Camera)

// 引數:名字,位置,所屬場景,失真補償(compensateDistortion),虛擬相機的指標(vrCameraMetrics)
var camera = new BABYLON.VRDeviceOrientationFreeCamera ("Camera", new BABYLON.Vector3 (-6.7, 1.2, -1.3), scene);

VR裝置定位弧度旋轉相機的構造(Constructing the VR Device Orientation Arc Rotate Camera)

// 引數:名字,縱向旋轉角度alpha,橫向旋轉角度beta,半徑,目標,所屬場景,失真補償(compensateDistortion),虛擬相機的指標(vrCameraMetrics) 
var camera = new BABYLON.VRDeviceOrientationArcRotateCamera ("Camera", Math.PI/2, Math.PI/4, 25, new BABYLON.Vector3 (0, 0, 0), scene);

VR裝置定位遊戲手柄相機的構造(Constructing the VR Device Orientation Gamepad Camera)

// 引數:名字,位置,所屬場景,失真補償(compensateDistortion),虛擬相機的指標(vrCameraMetrics)
var camera = new BABYLON.VRDeviceOrientationGamepadCamera("Camera", new BABYLON.Vector3 (-10, 5, 14));

WebVR自由相機(WebVR Free Camera)

    一種新型虛擬現實相機。

// 引數:名字,位置,所屬場景,WebVR選項
var camera = new BABYLON.WebVRFreeCamera("WVR", new BABYLON.Vector3(0, 1, -15), scene);

自定義輸入

    攝像機依靠使用者輸入來進行移動。如果你喜歡BabylonJs的預設相機,你可以繼續使用。如果您希望根據使用者偏好更改使用者輸入,那麼請定製現有的一個預置,或者使用自己的輸入機制。這些相機有一個為那些高階場景設計的輸入管理器。閱讀定製相機輸入,瞭解更多關於調整輸入您的相機。