1

I am using the gl-matrix library. For linear algebra calculations

I have a view and projection matrix that I used for my camera in a 3d engine. The view is a lookat matrix.

const view =  mat4.lookAt(
    [],
    camera.eye,
    camera.target,
    camera.up
  );

const projection = mat4.perspective(
     [],
     Math.PI / 4,
     viewport.width / viewport.height,
     0.1,
     1000.0
    );

I want to get the 8 camera frustum vertices from this camera setup to use in a bounding box for a shadow map.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
kevzettler
  • 4,783
  • 15
  • 58
  • 103

1 Answers1

2

At perspective projection the projection matrix describes the mapping from 3D points in the world as they are seen from of a pinhole camera, to 2D points of the viewport.
The eye space coordinates in the camera frustum (a truncated pyramid) are mapped to a cube (the normalized device coordinates).
In normalized device space the corner points of the view volume are the corners of a cube with the left, bottom, near of (-1, -1, -1) and the right, top, far of (1, 1, 1).

To get the points in view space, the points in normalized device space have to be transformed by the inverse projection matrix, followed by a Perspective divide.
A point in view space can be transformed to a point in world space, by the inverse view matrix.

The inverse matrix can be computed by mat4.invert. The code to transform a point from normalized device space to world space may be as follows:

inv_view = mat4.invert([], view);
inv_proj = mat4.invert([], projection);

ndc_corner = vec4.set([], -1, -1, -1, 1); // (-1, -1, -1) left, bottom, near

view_corner_h = vec4.transformMat4([], ndc_corner, inv_proj);
view_corner = vec4.scale([], view_corner_h, 1/view_corner_h[3]);

world_corner = vec4.transformMat4([], view_corner, inv_view);
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • what is the `w` component of `ndc_corner` and ? This is only for 1 corner how do you calculate the other 4 corners? – kevzettler Apr 01 '19 at 05:50
  • 1
    @kevzettler The `w` component belongs to the [Homogeneous coordinate](https://en.wikipedia.org/wiki/Homogeneous_coordinates) after the perspective projection. A frustum has 8 corner - all the permutations of -1 and 1 for the 3 coordinates x, y, and z. The 4 points at the near plane in counter clockwise order are (-1, -1, -1), (1, -1, -1), (1, 1, -1), (-1, 1, -1). – Rabbid76 Apr 01 '19 at 05:55
  • ok and then the far plane is `z + projection far distance` ? `(-1,-1,-1) + (0,0,projectionFar)` ? – kevzettler Apr 01 '19 at 14:43
  • 1
    I'd say that a *pinhole* projection doesn't employ a near plane which in turn results in different properties compared to the frustum based projection matrix generated by the `perspective` function of gl-matrix. – LJᛃ Apr 02 '19 at 02:46
  • @LJᛃ Yes of course. But the point is that at perspective projection the scene is from a point, in compare to orthographic projection. The near and far plane are related to accuracy ant mathematics - it's easy to compute. – Rabbid76 Apr 02 '19 at 04:27
  • @Rabbid76 how do you compute then? – kevzettler Apr 08 '19 at 23:43
  • @kevzettler What do you mean. The comment above doesn't change your computation. – Rabbid76 Apr 09 '19 at 04:50