BABYLON学习笔记二:相机

730 阅读3分钟

相机

通用相机(Universal Camera)

弧形旋转相机(ArcRotateCamera)

跟随相机(FollowCamera)

立体相机(AnaglyphCameras)

设备定向相机(Device Orientation Camera)

虚拟操纵杆相机(Virtual Joysticks Camera)

虚拟现实设备定向摄像机(VR Device Orientation Camera)

WebVR自由相机(WebVR Free Camera)

通用相机(Universal Camera)

通用相机现在是babylon.js使用的默认相机,如果希望在场景中又fps的控件,这个是最佳选择。

通过创建一个freeCamera相机

let camera = new BABYLON.FreeCame('freecamera',new BABYLON.Vector3(0, 2, -10))

// 添加鼠标滚轮
camera.inputs.addMouseWheel()
// 添加方向键事件
camera.inputs.addKeyboard()
// 添加鼠标监听事件
camera.inputs.addMouse()

完整示例

import * as BABYLON from 'babylonjs'
import 'babylonjs-loaders'
/**
 * 创建一个通用相机
 */
export default class {
    engine: BABYLON.Engine
    scene: BABYLON.Scene
    constructor(canvas: HTMLCanvasElement) {
        this.engine = new BABYLON.Engine(canvas, true)
        this.scene = new BABYLON.Scene(this.engine)
        let camera = this.initCamera()

        var light1 = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 1, 0), this.scene);
        var light2 = new BABYLON.PointLight("light2", new BABYLON.Vector3(0, 1, -1), this.scene);
        var sphere = BABYLON.MeshBuilder.CreateBox("sphere", { size: 2 }, this.scene);
        this.renderer()
    }
    /* initCamera(){

    } */
    //free相机

    initCamera() {
        let camera = new BABYLON.FreeCamera('freecamera', new BABYLON.Vector3(0, 2, -10))
        // 添加鼠标滚轮
        camera.inputs.addMouseWheel()
        // 添加方向键事件
        camera.inputs.addKeyboard()
        // 添加鼠标监听事件
        camera.inputs.addMouse()

        camera.attachControl(true);
        return camera
    }

    renderer() {
        this.engine.runRenderLoop(() => {
            this.scene.render()
        })
        window.addEventListener("resize", () => {
            this.engine.resize();
        });
    }
}

 

 

弧形旋转摄像机(ArcRotateCamera)

给定指定位置,并且以该位置为中心围绕该目标旋转,可以通过光标和鼠标的触摸事件来控制

可以把他想象成一个围绕着目标旋位置运行的相机,或者抽象理解为一个围绕目标旋转的卫星,相对于他的目标(地球有三个参数设置)

alpha:纵向旋转的角度(可以理解为经度)

bate:维度旋转的角度(可以理解为维度)

rotate:半径

环境beta由于技术原因,设置为0或PI可能会导致问题,因此在这种情况下,beta偏移0.1弧度(约0.6度)。

beta顺时针方向增加(往后向前旋转,自能旋转,默认只能PI),而alpha逆时针(往由左向右边旋转 2PI)增加。

通过ctry方向键可以使相机移动

设置amera.panningSensibility = 0;会禁止他移动

重要属性
minZ:定义相机能到的最远距离
maxZ:定义相机能看到最远距离
fov: 定义相机的视界
inertia:惯性,定义相机的移动数据
wheelDeltaPercentage: 设置鼠标滚轮速度,当你靠近目标物体时,变焦会变慢

代码示例

import * as BABYLON from 'babylonjs'
import 'babylonjs-loaders'
import * as GUI from 'babylonjs-gui';
/**
 * 创建一个通用相机
 */
export default class {
    engine: BABYLON.Engine
    scene: BABYLON.Scene
    constructor(canvas: HTMLCanvasElement) {
        this.engine = new BABYLON.Engine(canvas, true)
        this.scene = new BABYLON.Scene(this.engine)
        let camera = this.initCamera()
        // camera.fov = 0.8
        var light1 = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 1, 0), this.scene);
        var light2 = new BABYLON.PointLight("light2", new BABYLON.Vector3(0, 1, -1), this.scene);
        var sphere = BABYLON.MeshBuilder.CreateBox("sphere", { size: 2 }, this.scene);
        this.renderer()
    }
    /* initCamera(){

    } */
    //free相机

    initCamera() {
        let dom = document.createElement('div')
        document.querySelector('#app')?.appendChild(dom)
        dom.style.background = '#fff'
        dom.style.width = '60px'
        dom.style.height = '30px'
        dom.style.position = 'absolute'

        let camera = new BABYLON.ArcRotateCamera('freecamera', 0, 0, 10, new BABYLON.Vector3(0, 0, 0))
        let rotateTarget = 'beta', rotate = 0
        // camera.minZ = 10

        camera.speed = 0.001

        camera.lowerRadiusLimit = 2
        camera.upperRadiusLimit = 10
        // camera.inertia =
            camera.wheelDeltaPercentage = 0.01

        dom.innerText = rotateTarget
        setInterval(() => {

            rotate++
            if (rotate > 400) {
                rotate = 0
                rotateTarget = rotateTarget == 'beta' ? 'alpha' : 'beta'

                dom.innerText = rotateTarget
            }
            console.log(rotateTarget)
            if (rotateTarget == 'beta') {
                camera.beta = (rotate / 200) * Math.PI
            } else {
                camera.alpha = (rotate / 200) * Math.PI
            }

            camera.update()
        }, 20)
        // 添加鼠标滚轮
        camera.inputs.addMouseWheel()
        // 添加方向键事件
        camera.inputs.addKeyboard()
        // 添加鼠标监听事件

        camera.attachControl(true);
        return camera
    }

    renderer() {
        this.engine.runRenderLoop(() => {
            this.scene.render()
        })
        window.addEventListener("resize", () => {
            this.engine.resize();
        });
    }
}

跟随相机

这跟随摄像机就像罐头上写的那样。给它一个网格作为目标,无论它现在在什么位置,它都会移动到一个目标位置来查看目标。当目标移动时,跟随的摄像机也会移动。

 

跟随摄像机的初始位置在创建时设置,然后目标位置用三个参数设置:

半径:与目标的距离

高度偏移:目标上方的高度;

旋转偏移:x y平面中围绕目标的目标角度,以度为单位。

代码示例

import * as BABYLON from 'babylonjs'
import 'babylonjs-loaders'
/**
 * 创建一个跟随相机
 */
export default class {
    engine: BABYLON.Engine
    scene: BABYLON.Scene
    constructor(canvas: HTMLCanvasElement) {
        this.engine = new BABYLON.Engine(canvas, true)
        this.scene = new BABYLON.Scene(this.engine)

        var light1 = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 1, 0), this.scene);
        var light2 = new BABYLON.PointLight("light2", new BABYLON.Vector3(0, 1, -1), this.scene);
        var sphere = BABYLON.MeshBuilder.CreateBox("sphere", { size: 2 }, this.scene);
        for (let i = 0; i < 150; i++) {
            let mesh = BABYLON.MeshBuilder.CreateBox('boxs', { size: 0.3 }, this.scene)
            mesh.position = new BABYLON.Vector3(i * 0.5-15, 0, -1)
        }
        let camera = this.initCamera(sphere)
        this.initAnimation(sphere)
        this.renderer()
    }
    /* initCamera(){

    } */
    // 给他初始化一个动画
    initAnimation(mesh: BABYLON.Mesh) {
        const frameRate = 20
        let an = new BABYLON.Animation('move', 'position.x', frameRate, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE)
        let keys = [{ frame: 0, value: 0 }, { frame: 2 * frameRate, value: 5 }, { frame: 4 * frameRate, value: 0 }]
        an.setKeys(keys)
        mesh.animations.push(an)
        this.scene.beginAnimation(mesh, 0, 40 * frameRate, true);
    }
    //followCamera相机
    initCamera(target: BABYLON.Mesh) {
        let camera = new BABYLON.FollowCamera('freecamera', new BABYLON.Vector3(0, 2, -10))
        camera.radius = 30
        camera.heightOffset = 10
        camera.cameraAcceleration = 0.005
        camera.maxCameraSpeed = 10;
        camera.lockedTarget = target

        /* let camera = new BABYLON.FreeCamera('freecamera', new BABYLON.Vector3(0, 2, -10))
        // 添加鼠标滚轮
        camera.inputs.addMouseWheel()
        // 添加方向键事件
        camera.inputs.addKeyboard()
        // 添加鼠标监听事件
        camera.inputs.addMouse() */

        camera.attachControl(true);
        return camera
    }

    renderer() {
        this.engine.runRenderLoop(() => {
            this.scene.render()
        })
        window.addEventListener("resize", () => {
            this.engine.resize();
        });
    }
}

 

其他相机

后续还有“立体相机(AnaglyphUniversalCamera)“;

“设备定向相机(DeviceOrientationCamera)”;

“虚拟操纵杆相机”(VirtualJoysticksCamera);

虚拟操纵杆定向自由相机(VRDeviceOrientationFreeCamera)

构建虚拟现实设备定向圆弧旋转摄像机(VRDeviceOrientationArcRotateCamera)

构建虚拟现实设备定向游戏手柄相机(VRDeviceOrientationGamepadCamera)

WebVR自由相机(WebVRFreeCamera)

飞行相机(FlyCamera)

时间有限,由于目前没有了解到,就暂时不做介绍