WebGL Camera Transformation

←Back

Related Topics: OpenGL Camera

Overview

camera in ele space
Virtual Camera in Eye Space
OrbitCamera.js is a JavaScript class to manipulate a camera in a 3D scene and to provide the view matrix to GLSL shader after transformations. With this class, you can rotate, translate the camera object.

Please note the camera object in WebGL is virtual (does not exist). Instead, we inversely transform the whole vertex data in the scene from the world space to the eye space using the view matrix, where the virtual camera is positioned at (0, 0, 0) and always facing to -Z axis in the eye space. For example, rotating the camera left is equivalent to rotating the whole scene to right, and shifing the camera left is same as shifting the scene to right.

Camera LookAt

With lookAt() function, you can rotate the camera to the given target point from the camera position. It is used for an orbital camera interface which is always facing to the target object. The view matrix of lookAt() consists of 2 transformation parts; translation matrix MT and rotation matrix MR.
marrix for lookAt

FunctionDescription
lookAt(px,py,pz, tx,ty,tz)Position the camera at (px, py, pz) and rotate to (tx, ty, tz)

Please see how to construct the lookAt matrix for details. A typical usage of lookAt() follows;


// global var
let gl = {};
...

// create camera object with position (0,0,5) and looking to target (0,0,0)
gl.camera = new OrbitCamera(0,0,5, 0,0,0);

// lookat from position (1,2,3) to target (0,0,0)
gl.camera.lookAt(1,2,3, 0,0,0);
...

// pass view matrix to shader
gl.uniformMatrix4fv(gl.program.uniform.matrixView, false, gl.camera.matrix.m);
...

Camera Rotation (Pitch, Yaw, Roll)

camera rotations
Camera Rotations: Pitch, Yaw and Roll

Pitch is rotating the camera along the camera's local X-axis, Yaw is rotating it along Y-axis and Roll is rotating it along Z-axis. These rotations are used for first-person shooter style games. Visit OpenGL Camera Rotation page to learn more about how to construct the camera rotation matrix.

Please note that matrix muliplication is not cummutative. If you combine pitch, yaw and roll together, the different order of multiple rotations produces a different result. A common sequence of rotations is Roll → Yaw → Pitch.

OrbitCamera class provides rotateTo() to rotate it to the given angles (degrees) or quaternion. It also allows gradual animation for the given duration (ms). If the duration is not specified, the camera will snap to the target angles immediately.

FunctionDescription
rotateTo(to, duration)Rotate to the target angles or quaternion
(If duration is given, rotate this gradually.)


// global var
let gl = {};
...

// create camera object with position (0,0,5) and target (0,0,0)
gl.camera = new OrbitCamera(0,0,5, 0,0,0);

// rotate camera with pitch=30, yaw=40, duration=1000ms
let angle = new Vector3(30, 40, 0);     // degree angles
gl.camera.rotateTo(angle);              // snap to the angle immediately
gl.camera.rotateTo(angle, 1000);        // rotate gradually for 1 sec
...

// rotate camera with quaternion for 2000ms
let q = Quaternion.toQuaternionFromAngles(1, 2, 0); // radian angles to q
gl.camera.rotateTo(q);                  // snap to the quaternion immediately
gl.camera.rotateTo(q, 2000);            // gradually rotate for 2 sec
...

Camera Translation (Shift and Forward)

camera local axis
Camera Local Axis: Left, Up and Forward

In the camera interface for first-person shooter games, you want to move left/right or forward/backward in the 3D scene. These translations require shifting a delta movement along the camera's local axis; Left (X-axis), Up (Y-axis) and Forward (Z-axis) vectors.

You can acquire these local axis directly from its view matrix;
camera's left up and forward vectors

Please see how to derive the camera's local axis for details. Common interfaces for the camera translations are;

FunctionDescription
shift(delta, duration)Move left/right and up/down by the delta amount (deltax, deltay)
(If duration is given, move this gradually.)
moveForward(delta, duration)Move forward/backward by the delta amount, deltaz
(If duration is given, move this gradually.)
moveTo(to, duration)Move this position to the target position (tox, toy, toz)
(If duration is given, move this gradually.)
startShift(dir, accel)Start to shift to the given direction and acceleration
stopShift()Stop shifting
startForward(speed, accel)Start to move forward/backward to the given speed and acceleration
(If the speed is positive, it moves forward.)
stopForward()Stop forwarding

// global var
let gl = {};
...

// create camera object with position (0,0,5) and target (0,0,0)
gl.camera = new OrbitCamera(0,0,5, 0,0,0);

// shift camera left and up by (10, 20), duration=1000ms
let delta = new Vector2(10, 20);
gl.camera.shift(delta);                 // shift by delta immediately
gl.camera.shift(delta, 1000);           // shift gradually for 1 sec
...

// forward camera by 5, duration=1000ms
gl.camera.moveForward(5);               // forward immediately
gl.camera.moveForward(5, 1000);         // forward gradually for 1 sec
...

// move camera position to (10, 20, 30), duration=2000ms
let to = new Vector3(10, 20, 30);
gl.camera.moveTo(to);                   // move immediately
gl.camera.moveTo(to, 2000);             // move gradually for 2 sec
...

Example: Camera Interface

This example demonstrates how to implement the camera interface with JavaScript pointer event API (mouse + touch + stylus). It also binds the keyboard events. You can use the arrow keys to shift the camera and +/- key to move forward/backward.


decoration Fullscreen Demo: test_cameraOrbit.html
decoration GitHub Repo: test_cameraOrbit.html

←Back
 
Hide Comments
comments powered by Disqus