bntre/reverse-perspective-threejs: Reverse Perspective Camera for OpenGL (Three.js)

This example demonstrates how to build a custom OpenGL projection matrix that allows a seamless transition between three types of projection: direct perspective, orthographic projection, and reverse perspective.

For background, see https://en.wikipedia.org/wiki/Revers_perspective.
This visual effect is somewhat similar to the famous “Dolly Zoom” (https://en.wikipedia.org/wiki/Dolly_zoom), but more radical in nature.

Try it live: https://bntre.github.io/reverse-perspective-threejs/

Demo Video: https://www.youtube.com/watch?v=_5xI7a7cxBg

video cover

In this approach, the position of the camera becomes irrelevant when the projection is changed.
What really matters is how the shape of the frustum changes.

The type of perspective is defined by the inclination angle of a single projection ray:

  • p > 0 corresponds to direct perspective
  • p = 0 matches the orthographic projection
  • p < 0 corresponds to the opposite perspective

Within the usual near and far clip planes, a so-called focus plane is introduced. As the projection changes, the shape of this plane remains constant.

Estimate

Estimate

It is convenient to define the projection matrix by placing the camera at the center of the focus plane (so that near < 0 and away > 0), and by defining P As the tangent of the angle of the projection ray passing through the point (1, 0, 0),

The resulting projection matrix has the following form:

  [ Sx  0   0   0
    0   Sy  0   0
    0   0   A   B
    0   0   -p  1 ]

Value A And b The calculation is done in such a way that Jade coordinate range [near, far] map for [-1, 1] In clip space.

See the updateProjectionMatrix() function for details:
https://github.com/bntre/reverse-perspective-threejs/blob/main/index.html#L51

For more information about projection matrices, see Song Ho Ahn’s excellent article: https://www.songho.ca/opengl/gl_projectionmatrix.html

  • Animated model from three.js examples
    (Models are not included in this repo; they are loaded at runtime from the three.js repository):



Leave a Comment