Skip to content

Camera

The camera is a tool for displaying or capturing the virtual world for users, just like the eyes that observe things in the real world. All 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 commonly used camera types and controllers, and users can also extend the camera's functionality through custom components.

Basic Usage

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

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

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

ts
// If there are multiple cameras
let cameraObj1 = new Object3D();
let camera1 = cameraObj.addComponent(Camera3D);
let cameraObj2 = new Object3D();
let camera2 = cameraObj.addComponent(Camera3D);

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

Camera Position

There are three main 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
let camera = cameraObj.addComponent(Camera3D);
// Set the Position or Rotation of the Object3D 
cameraObj.x = 10;
cameraObj.rotateX = 90;
...
  1. By the component's lookAt function: The lookAt function provided by the camera component can set both the position of the camera Object3D and the position of the observation target at the same time:
ts
// Create a node
let cameraObj = new Object3D();
// Add a camera component
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 camera's up directionVector3(0, 1, 0)
  1. Camera Controller: Several common controller components are built into the engine, which can automatically adjust the position property of the camera according to the user's input interaction.

Camera Type

Currently, orthographic cameras and perspective cameras are mainly supported for developers to use.

Orthographic Projection

In orthographic camera mode, the size of the object in the rendering result does not change regardless of whether the object is far from or near 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 any distortion.

camera_orthoOffCenter

Calling the camera.orthoOffCenter API allows you to customize an orthographic camera space:

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

In general, we can quickly set up an orthographic space centered on the camera target, with frustumSize as the height and frustumSize as the depth, using camera.ortho. It keeps the screen ratio and automatically calculates left and right, and automatically calculates the near and far values of the viewing frustum based on the camera target as the base point.

ParameterTypeDescriptionExample
frustumSizenumberHeight of the frustum100
frustumDepthnumberDepth of the frustum100

Perspective Projection

Perspective projection uses 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 an observation effect close to the human eye. It is the most commonly used projection mode in 3D scenes.

camera_perspective

Calling camera.perspective allows you to set the camera as a perspective camera as needed:

ParameterTypeDescriptionExample
fovnumberPerspective degree60
aspectnumberViewport ratiowindow.innerWidth / window.innerHeight
nearnumberNear clipping plane0.1
farnumberFar clipping plane1000

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

<
ts
import { Engine3D, Scene3D, AtmosphericComponent, HoverCameraController, Object3D, MeshRenderer, BoxGeometry, LitMaterial, DirectLight, View3D, Camera3D, Frustum, OrbitController, Vector3, Color, AxisObject, GridObject } from "@orillusion/core";
import * as dat from "dat.gui"

// initializa engine
let engine = await Engine3D.init();

// create new scene as root node
let scene3D: Scene3D = new Scene3D();

// add an Atmospheric sky enviroment
let sky = scene3D.addComponent(AtmosphericComponent);
sky.sunY = 0.6;

// create camera
let cameraObj: Object3D = new Object3D();
let camera = cameraObj.addComponent(Camera3D);
// adjust camera view
camera.perspective(45, engine.aspect, 0.1, 1000.0);
camera.lookAt(new Vector3(0, 10, 10), Vector3.ZERO, Vector3.UP)
// set camera controller
let controller = cameraObj.addComponent(OrbitController);
controller.maxDistance = 200;
// add camera node
scene3D.addChild(cameraObj);

// create light obj
let light: Object3D = new Object3D();
// adjust light rotation
light.rotationX = 45;
light.rotationY = 30;
// add direct light component
let dirLight: DirectLight = light.addComponent(DirectLight);
dirLight.intensity = 3;
// add light object to scene
scene3D.addChild(light);

// create a box
const box: Object3D = new Object3D();
// add MeshRenderer
let mr: MeshRenderer = box.addComponent(MeshRenderer);
// set geometry
mr.geometry = new BoxGeometry(1, 1, 1);
// set material
mr.material = new LitMaterial();
// set rotation
box.y = 0
scene3D.addChild(box);

// create a box
const box2: Object3D = new Object3D();
// add MeshRenderer
let mr2: MeshRenderer = box2.addComponent(MeshRenderer);
// set geometry
mr2.geometry = new BoxGeometry(1, 1, 1);
// set material
mr2.material = new LitMaterial();
mr2.material.baseColor = Color.COLOR_RED
// set rotation
box2.y = 1
box2.x = 1
scene3D.addChild(box2);

// create a box
const box3: Object3D = new Object3D();
// add MeshRenderer
let mr3: MeshRenderer = box3.addComponent(MeshRenderer);
// set geometry
mr3.geometry = new BoxGeometry(1, 1, 1);
// set material
mr3.material = new LitMaterial();
mr3.material.baseColor = Color.COLOR_BLUE
// set rotation
box3.y = -1
box3.x = -1
scene3D.addChild(box3);

scene3D.addChild(new AxisObject(10));
scene3D.addChild(new GridObject(1000, 100));

// create a view with target scene and camera
let view = new View3D();
view.scene = scene3D;
view.camera = camera;
// start render
engine.startRenderView(view);

// add debug GUI
let gui = new dat.GUI();
let f = gui.addFolder('Camera')
let options = {
    'ortho': () => {
        camera.ortho(camera.frustumSize || 10, camera.frustumDepth || 50)
    },
    'perspective': () => {
        camera.near = 0.1
        camera.perspective(camera.fov, camera.aspect, camera.near, camera.far)
    }
}
f.add(camera, 'near', 0.1, 100).listen().onChange(() => {
    camera.type === 1 ? options.perspective() : options.ortho()
})
f.add(camera, 'far', 1, 1000).listen().onChange(() => {
    camera.type === 1 ? options.perspective() : options.ortho()
})
f.add(options, 'perspective')
f.add(camera, 'fov', 1, 179).listen().onChange(() => options.perspective())
f.add(options, 'ortho')
f.add(camera, 'frustumSize', 1, 200).listen().onChange(() => options.ortho())
f.add(camera, 'frustumDepth', 1, 200).listen().onChange(() => options.ortho())
f.open()

Camera Component

The camera component provides flexible extension support for the camera. You can use predefined components directly, or customize components to implement more personalized requirements. The component executes its own update logic, synchronized with the Engine3D main loop, through its own update function.

Fly Camera

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

  • Move forward, backward, left, and right toward the facing direction using W A S D
  • Control the movement orientation 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';

let engine = await Engine3D.init();
let scene: Scene3D = new Scene3D();
let cameraObj = new Object3D();
cameraObj.y = 0;
let camera = cameraObj.addComponent(Camera3D);
camera.perspective(60, engine.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
engine.startRenderView(view);

Basic usage:

ts
import { Scene3D, Camera3D, FlyCameraController } from '@orillusion/core'
// Instantiate a node
let cameraObj = new Object3D();
// Load a camera component
let camera = cameraObj.addComponent(Camera3D);
// Load the controller component
let flyController = cameraObj.addComponent(FlyCameraController);
// Set the camera position through the component's 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 set its own position and orientation through setCamera

ParameterTypeDescriptionExample
targetPosVector3Own positionnew Vector3(0,0,10)
lookAtPosVector3Target positionnew Vector3(0,0,0)

You can also modify moveSpeed to adjust the speed of movement

ParameterTypeDescriptionExample
moveSpeednumberMovement speed10

Hover Camera

This camera controller implements the camera's movement in the xz plane / 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 smoothly move the current scene's visible area according to the direction and distance of the mouse movement
  • 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';

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

let cameraObj = new Object3D();
let camera = cameraObj.addComponent(Camera3D);
camera.perspective(60, engine.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
engine.startRenderView(view);

Basic usage:

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

The hover camera can control the camera position and orientation through setCamera

ParameterTypeDescriptionExample
rollnumberRotate around the y axis0
pitchnumberRotate around the x axis0
distancenumberDistance between the camera and the target10
targetVector3Target coordinate to facenew Vector3(0,0,0)

Orbit Camera

This camera controller is very similar to the hover camera, also rotating around a coordinate observation point. But it can directly set the position and rendering of the camera's Object3D to control the view position and orientation. Its main features are as follows:

  • Press the left mouse button and move the mouse to rotate the camera omnidirectionally around the current observation target
  • Press the right mouse button and move the mouse to move the camera center in all spatial directions according to the direction of mouse movement, not only freely moving in the xz plane, but also supporting free movement in the y direction
  • Scroll the mouse wheel to control the distance between the camera and the center
  • You can set the camera to rotate automatically
  • You can set the speed of rotation, zoom, and panning
  • You can set the maximum and minimum elevation angles

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';

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

let cameraObj = new Object3D();
let camera = cameraObj.addComponent(Camera3D);
camera.perspective(60, engine.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
engine.startRenderView(view);

Basic usage:

ts
import { Scene3D, Camera3D, OrbitController } from '@orillusion/core'
// Instantiate a node
let cameraObj = new Object3D();
// Load a camera component
let camera = cameraObj.addComponent(Camera3D);
// Load the controller component
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 panning speed coefficient
orbit.panFactor = 0.25
// View smoothing coefficient
orbit.smooth = 5
// Minimum zoom distance
orbit.minDistance = 1
// Maximum zoom 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, and can refer to the implementation of OrbitController.

Released under the MIT License