Skip to content

Camera

Camera is a tool for users to display or capture the virtual world, just like the eyes that observe things in the real world. All the cool images need to be rendered through the camera. At least one camera must be present in each scene to view the objects in the scene. Orillusion has already encapsulated the camera types and controllers commonly used, and users can also extend the function of the camera by custom components.

Basic Usage

ts
import { Object3D, Scene3D, Camera3D } from '@orillusion/core'
// Initialize a scene
let scene = new Scene3D();
// Initialize a camera node
let cameraObj = new Object3D();
// Add a camera component to the node
let camera = cameraObj.addComponent(Camera3D);
// Add the camera node to scene
scene.addChild(cameraObj);

// Create 3D view
let view = new View3D();
// Fill the scene to the 3D view
view.scene = scene;
// Fill the camera to the 3D view
view.camera = camera;
// Start rendering
Engine3D.startRenderView(view);

If there are multiple cameras in the scene, you can manually switch the target camera through view.camera:

ts
// If multiple cameras exist in the scene
let cameraObj1 = new Object3D();
let camera1 = cameraObj.addComponent(Camera3D);
let cameraObj2 = new Object3D();
let camera2 = cameraObj.addComponent(Camera3D);

// Create 3D view
let view = new View3D();
// Set the rendering scene
view.scene = scene;
// camera1 Set camera1
view.camera = camera1;
...
// Switch to use camera2 for rendering
view.camera = camera2;

Camera Position

There are three ways to change the camera position:

  1. By TransForm transformation: The position and direction angle of the camera can be manually set through the transForm property of the camera node Object3D:
ts
// Create a node
let cameraObj = new Object3D();
// Add a camera component to the node
let camera = cameraObj.addComponent(Camera3D);
// Set the Position or Rotation of the Object3D
cameraObj.x = 10;
cameraObj.rotateX = 90;
...
  1. By lookAt function of the component: The lookAt function of the camera component can set the position of the camera Object3D and the position of the target to be observed at the same time:
ts
// Create a node
let cameraObj = new Object3D();
// Add a camera component to the node
let camera = cameraObj.addComponent(Camera3D);
// Use the lookAt function of the Camera3D component to change the position and direction angle of the Object3D
camera.lookAt(new Vector3(0,0,10), new Vector3(0,0,0), new Vector3(0,0,1));
ParameterTypeDescriptionExample
posVector3The position of the object itself (global)Vector3(0, 0, 0)
targetVector3The position of the target (global)Vector3(0, 1, 0)
upVector3The coordinate axis of the direction the camera is facing upVector3(0, 1, 0)
  1. Camera Controller: Several common controller components are built in the engine, which can automatically adjust the position properties of the camera according to the user's input interaction.

Camera Type

The engine mainly supports orthographic cameras and perspective cameras for developers to use currently.

Orthographic Projection

In orthographic camera mode, the size of the object does not change regardless of how far the object is from the camera. We usually use orthographic cameras in 2D drawing, and set the z coordinate to 0.0 in our geometric graphics. But the z axis can be extended to any length we want. Using an orthographic camera to project the display object, the result is scaled proportionally without distortion.

camera_orthoOffCenter

Use camera.orthoOffCenter API to set the camera to an orthographic camera:

ParameterTypeDescriptionExample
leftnumberThe minimum value of the x-axis of the viewing frustum-window.innerWidth / 2
rightnumberThe maximum value of the x-axis of the viewing frustumwindow.innerWidth / 2
bottomnumberThe minimum value of the y-axis of the viewing frustum-window.innerHeight / 2
topnumberThe maximum value of the y-axis of the viewing frustumwindow.innerHeight / 2
nearnumberThe z value of the near clipping plane of the viewing frustum1
farnumberThe z value of the far clipping plane of the viewing frustum5000

Perspective Projection

Perspective projection will use perspective division to shorten and shrink objects that are far away from the observer. Objects with the same logical size appear larger in the front position than in the back position in the visible area, which can achieve the observation effect close to the human eye. It is the most commonly used projection mode in 3D scenes.

camera_perspective

Use camera.perspective API to set the camera to a perspective camera:

ParameterTypeDescriptionExample
fovnumberThe perspective degree60
aspectnumberThe aspect ratio of the viewportwindow.innerWidth / window.innerHeight
nearnumberThe z value of the near clipping plane of the viewing frustum0.1
farnumberThe z value of the far clipping plane of the viewing frustum1000

WebGPU is not supported in your browser
Please upgrade to latest Chrome/Edge

<
ts
import { Engine3D, Vector3, Scene3D, Object3D, Camera3D, AtmosphericComponent, LitMaterial, BoxGeometry, MeshRenderer, HoverCameraController, View3D, CameraType, DirectLight } from '@orillusion/core';
import * as dat from 'dat.gui';

export default class CameraDemo {
    cameraObj: Object3D;
    camera: Camera3D;
    scene: Scene3D;

    constructor() {}

    async run() {
        await Engine3D.init({
            canvasConfig: {
                alpha: true
            }
        });
        await this.initScene();
        await this.initCamera();
        await this.createBoxes();

        let sky = this.scene.addComponent(AtmosphericComponent);
        sky.sunY = 0.6;
        sky.enable = false;

        // add a base light
        let lightObj = new Object3D();
        lightObj.addComponent(DirectLight);
        this.scene.addChild(lightObj);

        let view = new View3D();
        view.scene = this.scene;
        view.camera = this.camera;
        Engine3D.startRenderView(view);

        this.addGui();
    }

    async initScene() {
        this.scene = new Scene3D();
    }

    async initCamera() {
        this.cameraObj = new Object3D();
        this.camera = this.cameraObj.addComponent(Camera3D);
        this.camera.lookAt(new Vector3(0, 0, -350), new Vector3(0, 0, 0));
        let hc = this.cameraObj.addComponent(HoverCameraController);
        hc.setCamera(-90, 0, 500);
        this.scene.addChild(this.cameraObj);
        this.perspective();
    }

    async orthoOffCenter() {
        this.camera.orthoOffCenter(-window.innerWidth / 4, window.innerWidth / 4, -window.innerHeight / 4, window.innerHeight / 4, 1, 5000.0);
    }

    async perspective() {
        this.camera.perspective(60, Engine3D.aspect, 1, 10000.0);
    }

    async createBox(name: string) {
        let obj: Object3D = new Object3D();
        obj.name = name;
        let mr: MeshRenderer = obj.addComponent(MeshRenderer);
        mr.geometry = new BoxGeometry(50, 50, 50);
        mr.material = new LitMaterial();
        return obj;
    }

    async createBoxes() {
        for (let i = -1; i < 2; ++i) {
            let obj = await this.createBox('cube_' + i);

            obj.x = 0;
            obj.y = i * -60;
            obj.z = i * -60;

            this.scene.addChild(obj);
        }
    }

    async addGui() {
        const GUIHelp = new dat.GUI();
        GUIHelp.addFolder('Camera Type');
        GUIHelp.add({ Perspective: () => this.perspective() }, 'Perspective');
        GUIHelp.add({ Orthographic: () => this.orthoOffCenter() }, 'Orthographic');

        window.addEventListener('resize', () => {
            if (this.camera.type === CameraType.ortho) this.orthoOffCenter();
        });
    }
}
new CameraDemo().run();
document.body.style.background = '#aaa';

Camera Conponent

The Camera component provides flexible extension support for the camera, which can be used directly with predefined components, or can be customized to implement more personalized requirements. The component executes its own update logic in sync with the Engine3D main loop through its update function.

FlyCamera

This controller implements the camera's free movement. Its interaction features are:

  • Move forward, backward and left and right by pressing W A S D
  • Control the movement direction of the camera by holding down the left mouse button

WebGPU is not supported in your browser
Please upgrade to latest Chrome/Edge

<
ts
import { Engine3D, Scene3D, Object3D, Camera3D, Vector3, PlaneGeometry, DirectLight, Color, KelvinUtil, FlyCameraController, AtmosphericComponent, LitMaterial, BoxGeometry, MeshRenderer, View3D } from '@orillusion/core';

await Engine3D.init();
let scene: Scene3D = new Scene3D();
let cameraObj = new Object3D();
cameraObj.y = 0;
let camera = cameraObj.addComponent(Camera3D);
camera.perspective(60, Engine3D.aspect, 0.1, 5000.0);

// add Camera Controller
let flyController = cameraObj.addComponent(FlyCameraController);
flyController.setCamera(new Vector3(0, 15, 15), new Vector3(0, 10, 0));
flyController.moveSpeed = 10;
scene.addChild(cameraObj);

const boxObj: Object3D = new Object3D();
boxObj.localPosition = new Vector3(0, 10, 0);
let boxMr: MeshRenderer = boxObj.addComponent(MeshRenderer);
boxMr.geometry = new BoxGeometry(2, 2, 2);
boxMr.material = new LitMaterial();
boxMr.material.baseColor = new Color(1.0, 1.0, 1.0, 1.0);
scene.addChild(boxObj);

let groundObj = new Object3D();
groundObj.localPosition = new Vector3(0, 9, 0);

let planeMr = groundObj.addComponent(MeshRenderer);
planeMr.geometry = new PlaneGeometry(10, 10);

planeMr.material = new LitMaterial();
scene.addChild(groundObj);

{
    let lightObj = new Object3D();
    lightObj.x = 0;
    lightObj.y = 0;
    lightObj.z = 0;
    lightObj.rotationX = 0;
    lightObj.rotationY = 0;
    lightObj.rotationZ = 0;
    let lc = lightObj.addComponent(DirectLight);
    lc.lightColor = KelvinUtil.color_temperature_to_rgb(5355);
    lc.castShadow = true;
    lc.intensity = 1.7;
    scene.addChild(lightObj);
}

// add an Atmospheric sky enviroment
scene.addComponent(AtmosphericComponent).sunY = 0.6;
// create a view with target scene and camera
let view = new View3D();
view.scene = scene;
view.camera = camera;
// start render
Engine3D.startRenderView(view);

Basic usage:

ts
import { Scene3D, Camera3D, FlyCameraController } from '@orillusion/core'
// Create a node
let cameraObj = new Object3D();
// Add a camera component to the node
let camera = cameraObj.addComponent(Camera3D);
// Add a controller component to the node
let flyController = cameraObj.addComponent(FlyCameraController);
// Set the camera position through the component setCamera
flyController.setCamera(new Vector3(0, 0, 15), new Vector3(0, 0, 0));
// Set the mouse movement speed
flyController.moveSpeed = 10;

The fly camera can be set by setCamera to set its own position and orientation

ParameterTypeDescriptionExample
targetPosVector3The position of the cameranew Vector3(0,0,10)
lookAtPosVector3The position of the targetnew Vector3(0,0,0)

Also, you can modify moveSpeed to adjust the speed of movement

ParameterTypeDescriptionExample
moveSpeednumberThe speed of movement10

HoverCamera

This camera controller implements the camera's movement in the xz plane and rotation around the current observation point. Its interaction features are:

  • Press the left mouse button and move the mouse to rotate the camera around the current observation target.
  • Press the right mouse button and move the mouse to pan the camera in various directions in both xz plane and y direction.
  • Scroll the mouse wheel to control the camera's viewing distance

WebGPU is not supported in your browser
Please upgrade to latest Chrome/Edge

<
ts
import { Engine3D, Scene3D, Object3D, Camera3D, Vector3, HoverCameraController, AtmosphericComponent, LitMaterial, BoxGeometry, MeshRenderer, View3D, DirectLight } from '@orillusion/core';

await Engine3D.init();
let scene: Scene3D = new Scene3D();

let cameraObj = new Object3D();
let camera = cameraObj.addComponent(Camera3D);
camera.perspective(60, Engine3D.aspect, 0.1, 5000.0);

// add camera controller
let hoverController = cameraObj.addComponent(HoverCameraController);
hoverController.setCamera(15, -15, 15, new Vector3(0, 0, 0));
scene.addChild(cameraObj);

// add a base light
let lightObj = new Object3D();
lightObj.addComponent(DirectLight);
scene.addChild(lightObj);

const boxObj: Object3D = new Object3D();
boxObj.localPosition = new Vector3(0, 0, 0);

let mr: MeshRenderer = boxObj.addComponent(MeshRenderer);
mr.geometry = new BoxGeometry(5, 5, 5);
mr.material = new LitMaterial();

scene.addChild(boxObj);

// add an Atmospheric sky enviroment
scene.addComponent(AtmosphericComponent).sunY = 0.6;
// create a view with target scene and camera
let view = new View3D();
view.scene = scene;
view.camera = camera;
// start render
Engine3D.startRenderView(view);

Basic usage:

ts
import { Scene3D, Camera3D, HoverCameraController } from '@orillusion/core'
// Create a node
let cameraObj = new Object3D();
// Add a camera component to the node
let camera = cameraObj.addComponent(Camera3D);
// Add a controller component to the node
let hoverCameraController = cameraObj.addComponent(HoverCameraController);
// Set the camera position through the component setCamera
hoverController.setCamera(15, -15, 15, new Vector3(0, 0, 0));

The hover camera can be controlled by setCamera to set its own position and orientation

ParameterTypeDescriptionExample
rollnumberRotate around the y axis0
pitchnumberRotate around the x axis0
distancenumberDistance from the target10
targetVector3Target coordinatenew Vector3(0,0,0)

Orbit

This camera controller is similar to the hover camera, but it can directly set the position and orientation of the camera Object3D to control the position and orientation of the view. The main features are as follows:

  • Press the left mouse button and move the mouse to rotate the camera around the current observation target.
  • Press the right mouse button and move the mouse to move the camera smoothly in the direction and distance of the mouse movement in the current scene visible area.
  • Scroll the mouse wheel to control the camera's viewing distance
  • You can set the camera to automatically rotate
  • You can set the rotation, zoom, and translation speed
  • You can set the maximum and minimum angles of elevation

WebGPU is not supported in your browser
Please upgrade to latest Chrome/Edge

<
ts
import { Engine3D, Scene3D, Object3D, Camera3D, Vector3, OrbitController, AtmosphericComponent, LitMaterial, BoxGeometry, MeshRenderer, View3D, DirectLight } from '@orillusion/core';

await Engine3D.init();
let scene: Scene3D = new Scene3D();

let cameraObj = new Object3D();
let camera = cameraObj.addComponent(Camera3D);
camera.perspective(60, Engine3D.aspect, 0.1, 5000.0);
cameraObj.localPosition.set(0, 10, 20);

// add camera controller
let orbit = cameraObj.addComponent(OrbitController);
// auto rotation
orbit.autoRotateSpeed = 0.5;
orbit.autoRotate = true;
scene.addChild(cameraObj);

// add a base light
let lightObj = new Object3D();
lightObj.addComponent(DirectLight);
scene.addChild(lightObj);

const boxObj: Object3D = new Object3D();
boxObj.localPosition = new Vector3(0, 0, 0);
let mr: MeshRenderer = boxObj.addComponent(MeshRenderer);
mr.geometry = new BoxGeometry(5, 5, 5);
mr.material = new LitMaterial();

scene.addChild(boxObj);

// add an Atmospheric sky enviroment
scene.addComponent(AtmosphericComponent).sunY = 0.6;
// create a view with target scene and camera
let view = new View3D();
view.scene = scene;
view.camera = camera;
// start render
Engine3D.startRenderView(view);

Basic usage:

ts
import { Scene3D, Camera3D, OrbitController } from '@orillusion/core'
// Create a node
let cameraObj = new Object3D();
// Add a camera component to the node
let camera = cameraObj.addComponent(Camera3D);
// Add a controller component to the node
let orbit = cameraObj.addComponent(OrbitController);
// Set the position of the camera Object3D
cameraObj.localPosition.set(0, 10, 30);
// Enable automatic rotation
orbit.autoRotate = true
// Automatic rotation speed
orbit.autoRotateSpeed = 0.1
// Zoom speed coefficient
orbit.zoomFactor = 0.1
// View angle translation speed coefficient
orbit.panFactor = 0.25
// View angle smoothing coefficient
orbit.smooth = 5
// Zoom minimum distance
orbit.minDistance = 1
// Zoom maximum distance
orbit.maxDistance = 1000
// Minimum elevation angle
orbit.minPolarAngle = -90
// Maximum elevation angle
orbit.minPolarAngle = 90

Custom Controller

Users can extend additional camera components through custom components, See OrbitController as an example.

Released under the MIT License