The “Camera” and the Projection and View Transforms

Introduction

This article describes projection and view transforms commonly used in 3D graphics,
especially when using my HTML 3D Library.

Download the latest version of the library at the HTML 3D Library’s Releases page.

The "Camera" and the Projection and View Transforms

The Scene3D class of the HTML 3D Library has a concept of a "projection transform" and a "view transform". If we use the concept of a "camera", the projection is like setting the camera’s focus and lens, and the view transform is like setting its position and orientation. Scene3D has methods for setting all these attributes of this abstract "camera". Two of them are setPerspective() and setLookAt(), which are shown in the example below.

// Set the perspective view.  Camera has a 45-degree field of view
// and will see objects from 0.1 to 100 units away.
scene.setPerspective(45,scene.getClientAspect(),0.1,100);
// Move the camera back 40 units.
scene.setLookAt([0,0,40]);
// Move the camera back 30 units instead, and turn it so it
// points at (0, 2, 0), that is, up 2 units.
scene.setLookAt([0,0,30], [0,2,0]);

Overview of Transformations

Here is an overview of transformations used in the graphics system and
the HTML 3D library.

  • A world matrix transforms an object’s own coordinates to world space,
    the coordinate system shared by every object in the scene. The world matrix
    is not discussed in this article.
  • A view matrix transforms coordinates in world space to camera space or eye space.
  • A projection matrix transforms coordinates in camera space to clip space.
  • Additionally, the graphics pipeline (outside the HTML 3D library) converts the
    clip space coordinates to normalized device coordinates, then screen space
    coordinates when drawing objects on the screen.

Projection Transform

A projection matrix transforms coordinates in camera space to clip space.

Two commonly used projections in 3D graphics are the perspective projection and
orthographic projection, described below.

Perspective Projection

A perspective projection gives the 3D scene a sense of depth. In this projection, closer objects
look bigger than more distant objects with the same size.

Two rows of spheres, and a drawing of a perspective view volume.

Two rows of spheres, and a side drawing of a perspective view volume.

The 3D scene is contained in a so-called view volume, and only objects contained in the view volume
will be visible. The dark yellow lines above show what a perspective view volume looks like. The red spheres
would not be visible under this view volume.

The view volume is bounded on all six sides by six clipping planes:

  • The near and far clipping planes are placed a certain distance from the camera. For example, if
    the near clipping plane is 3 units away and the far clipping plane is 5 units away, the view volume
    will hold only objects between 3 and 5 units from the camera. (Strictly speaking, a near clipping
    plane is not necessary, but practically speaking it is, in order to make the math work out correctly.)
  • The left, right, top, and bottom clipping planes form the other four sides of the volume.

Note further that:

  • The angle separating the top and bottom clipping planes is the projection’s field of view. This is an angle
    similar to the aperture of a camera. The greater the vertical field of view, the greater
    the vertical visibility range.
  • In a perspective projection, the near clipping plane segment bounding the view volume is smaller than
    the far clipping plane segment. This is because the four other clipping planes are not parallel and extend
    from the eye position.

The perspective projection converts 3D coordinates to 4-element vectors in the form (X, Y, Z, W), also
known as clip coordinates. Since the graphics system (outside the HTML 3D library) only deals with
3D points, it divides the X, Y, and Z components by the W component to get the 3D point’s normalized
device coordinates
and achieve the perspective effect.

The Scene3D class’s setPerspective()
and setFrustum()
methods define a perspective projection.

scene3d.setPerspective(fov, aspect, near, far)

This method calculates the appropriate clipping planes given a field of view and an aspect ratio,
and sets the scene’s projection matrix accordingly.

  • fov – Vertical field of view, in degrees.
  • aspect – Aspect ratio of the scene. You should usually use scene3d.getClientAspect().
  • near, far – Distance from the camera to the near and far clipping planes.

scene3d.setFrustum(left, right, bottom, top, near, far)

This method sets the scene’s projection matrix based on the location of the six clipping planes that
bound the view volume. Their positions are chosen so that the result is a perspective projection.

  • left, right, bottom, top – Location of the left, right, bottom, and top clipping planes in terms
    of where they meet the near clipping plane.
  • near, far – Distance from the camera to the near and far clipping planes.

Demo

Orthographic Projection

An orthographic projection is one in which the left and right clipping planes are parallel to each other,
and the top and bottom clipping planes are parallel to each other. This results in the near and far clipping
planes having the same size, unlike in a perspective projection, and
objects with the same size not varying in size with their depth.

The Scene3D class’s setOrtho()
and setOrthoAspect() methods
define an orthographic projection.

scene3d.setOrtho(left, right, bottom, top, near, far)

This method calculates an orthographic projection.

  • left – Leftmost coordinate of the 3D view.
  • right – Rightmost coordinate of the 3D view.
  • bottom – Topmost coordinate of the 3D view.
  • top – Bottommost coordinate of the 3D view.
  • near, far – Distance from the camera to the near and far clipping planes. Either value
    can be negative.

scene3d.setOrthoAspect(left, right, bottom, top, near, far, aspect)

This method calculates an orthographic projection such that the resulting view isn’t stretched
or squished in case the view volume’s aspect ratio and the scene’s aspect ratio are different.

  • left, right, bottom, top, near, far – Same as in setOrtho.
  • aspect – Aspect ratio of the viewport. May be omitted, in which case the scene’s
    aspect ratio (scene.getClientAspect()) is used.

Other Projections

There are other kinds of possible projections, such as oblique projections
or isometric projections. For these
and other projections, you can specify a custom projection matrix to the 3D scene using the
setProjectionMatrix()
method.

scene3d.setProjectionMatrix(matrix)

This method allows you to set the projection matrix to an arbitrary 4×4 matrix.

  • matrix – The 4×4 matrix to use.

View Transform

The view matrix transforms world space coordinates, shared by every object in a scene, to camera space
coordinates, in which the camera is located at the center of the coordinate system: (0, 0, 0). A view matrix essentially rotates the camera and moves it to a given position in world space. Specifically:

  • The camera is rotated to point at a certain object or location on the scene. This is represented by
    the lookingAt parameter in the setLookAt() method, below.
  • The camera is placed somewhere on the scene. This is represented by
    the eye parameter in the setLookAt() method. It also represents the "eye position" in the perspective
    projection, above.
  • The camera rolls itself, possibly turning it sideways or upside down. This is represented by
    the up parameter in the setLookAt() method. Turning the camera upside down, for example, will swap
    the placement of the top and bottom clipping planes, thus inverting the view of the scene.

The setLookAt() and setViewMatrix() methods are described below.

scene3d.setLookAt(eye, lookingAt, up)

This method allows you to set a view matrix based on the camera’s position and view.

  • eye – Array of three elements (X, Y, Z) giving the position of the camera in world space.
  • lookingAt – Array of three elements (X, Y, Z) giving the position the camera is looking at in world space.
    This is optional. The default is [0, 0, 0].
  • up – Array of three elements (X, Y, Z) giving the vector from the center of the camera to the top.
    This is optional. The default is [0, 1, 0].

scene3d.setViewMatrix(matrix)

This method allows you to set the view matrix to an arbitrary 4×4 matrix.

  • matrix – The 4×4 matrix to use.

CodePlex and SourceForge mirrors of projects

Concise Binary Object Representation in C#

* CodePlex: https://peterocbor.codeplex.com/
* Code Project: http://www.codeproject.com/Tips/897294/Concise-Binary-Object-Representation-CBOR-in-Cshar

* SourceForge: https://sourceforge.net/p/petero-cbor

Public Domain HTML 3D Library

* CodePlex: https://html3dutil.codeplex.com/
* Code Project: http://www.codeproject.com/Tips/896839/Public-Domain-HTML-ThreeD-Library
* SourceForge: https://sourceforge.net/p/html3dutil

Version 1.2 of Public Domain HTML 3D Library released

Version 1.2:

– Support TGA textures
– Camera class rewritten and support added for the mouse wheel
and middle mouse button
– Lines and points supported in OBJ files
– Support loading custom textures from byte arrays
– Add method to create capsule shapes in Meshes class
– Mesh builder (vector3 method) avoids adding degenerate triangles
– Optimizations and bug fixes

https://github.com/peteroupc/html3dutil/releases/tag/v1.2.0

HTML 3D library for Web developers; upokecenter.com down

If you make Web pages, you may find this interesting.

https://github.com/peteroupc/html3dutil – A public domain JavaScript library for easing
the development of HTML 3D applications. I’ve worked on this lately, and it now
has extensive documentation and examples.

https://github.com/peteroupc/canvasback – Displays an HTML canvas-based background
that draws boxes in about the same color as the background color. An easy-to-use background
for your Web sites. View the demo: http://peteroupc.github.io/canvasback/canvasback.html

——————–

The upokecenter.com site is down. Please donate to help my pay my expenses
for restoring it, which are not my only expenses. Visit: http://upokecenter.dreamhosters.com/articles/donate-now-2/

“allow to do” something, “remind to do” something

To say that something “allows to do something” is not the usual form in English. In my experience, this appears to be a common mistake of non-native English speakers, since a similar construction does occur in some other languages, such as Spanish (permitir hacerlo and not permitir haciéndolo)

Much more common is adding the somebody to the expression. “Allows you to do something” or “Allows many people to do something”. Or use a gerund (doing) instead of an infinitive (to do): “Allows doing something”.

A similar construction that’s potentially problematic is the form “remind to do something” (such as “This program reminds to eat right every day”). The verb remind in English always requires saying which person is being reminded. This is also unlike other languages. For instance, in Spanish using the verb recordar: Esta aplicación recuerda comer bien. Incidentally, the verb recordar also means “to remember”. But the verb remember means something slightly different: “I remember to eat well” means “I remind myself to eat well”. Saying “This program remembers to eat right” would mean “This program reminds itself to eat right”, so the meaning would be different.

Accordingly the correct form is “This program reminds you (or me, or people) to eat right every day.”

Articles and pages by the owner of The Ultimate Pokemon Center