The following material is probably familiar, or even well known, to programmers who had experience with OpenGL, meanwhile, I found it appropriate to recall the
oblique frustum model, partially observing (and sharing) the interest of
Habr's readers in OpenGL issues and in general three-dimensional modeling, partly because of disagreement with the position of some developers like
“... in order to use it, it is not at all necessary to understand how the projection matrix works,” partly out of respect and gratitude for Eric Lengel |
Eric Lengyel , whose inventive thought has enriched the techniques of working in the OpenGL environment.
If there are mirror images in the scenes you are modeling and you have forgotten or not heard about “oblique frustum”, then it is possible that this article will not be useless for you.
In spite of the fact that I, following Erik Lengel, were more adhered to in presenting the material of OpenGL presentations, all the subsequent reasoning is easily extended to any other three-dimensional modeling systems.

')
Reflections in 3D scenes
In the case where reflective surfaces are present in 3D scenes, the usual practice of obtaining reflections is to render the scene using an auxiliary view camera, which itself is a reflection of the main view camera by the plane of the reflecting surface.
Fig . 1. The top camera is the main camera through which the scene containing the reflective surface is rendered. The bottom camera is
an auxiliary camera designed for rendering reflection. The X axis is directed to the observer for both the pyramids of visibility (
in the views adopted for OpenGL ), and it is obvious that the coordinate system for the camera that renders the reflection is
left-handed .
When rendering a reflection with an auxiliary camera (a reflection camera), it may turn out that some of the objects located between the observer and the reflecting surface end up in the resulting render, forming unwanted artifacts in the image. In order to cut off the undesirable part of the reflected scene from the final render, the programmer restricts the part of the volume of the three-dimensional scene observed from the reflection chamber to an imaginary surface, using various techniques to interrupt the rendering of the scene beyond this surface.
You can use the “discard” instruction for a fragmentary shader or similar, specific for individual rendering implementations in the general ideology of 3D modeling (for example, kill in AGALMiniAssembler), however, if we want a universal solution that works equally well
on any processor , then pay attention to the technique proposed by Eric Lengel.
The idea of ​​Eric Lengela was to modify the
projection matrix in such a way that the
near view of the visibility pyramid becomes just a sort of
cutting plane that separates the volume of the main scene that is undesirable in the final render.
For further, it is appropriate to recall the elementary representations of
analytic geometry .
Plane in space
For convenience of presentation, we will adhere to the following notation:
![\ begin {center} \ begin {array} {| rlc} \ textbf {for points and vectors:} & amp; \ vec {A}, \ vec {P} \\ \ multicolumn {2} {| l} {\ textit {distinguishing them} \ mathit {w} \ textit {-coordinate in a uniform representation,}}} \\ \ multicolumn { 2} {| l} {\ textit {the coordinate record is enclosed in angle brackets} \ langle ,,, \ rangle} \\ [0.3em] \ textbf {for matrices:} & amp; \ mathbf {M}, \ mathbf {P} \\ \ textbf {transposed matrix:} & amp; \ mathbf {M} ^ \ mathrm {T} \\ \ textbf {inverse matrix:} & amp; \ mathbf {M} ^ {- 1} \\ \ textbf {character} x: & amp; sgn (x) = \ begin {cases} 1, & amp; \ quad \ text {if} x & gt; 0 \\ 0, & amp; \ quad \ text {if} x = 0 \\ -1, & amp; \ quad \ text {if} x & lt; 0 \ end {cases} \\ \ textbf {vector length:} & amp; \ | \ vec {P} \ | \\ \ textbf {scalar product of vectors:} & amp; \ vec {Q} \ cdot \ vec {P} \\ \ end {array} \ end {center}](https://habrastorage.org/getpro/habr/post_images/e9e/e1c/929/e9ee1c9295cf0323549ad848be7f8843.svg)
Plane
For any spatial 3D point

and vectors

, set of 3D points

other than

satisfying the equation

defines a plane, with a point

is one of the points belonging to this plane, and the vector

is its normal vector.
Fig . 2. The plane is completely determined by the point belonging to it.

and normal vector

.
The plane equation is often written with the following expression:

Where

and

there is

normal vector components

, and

. Value

equal to the distance to the plane from the origin (
remember that the components of the normal vector divided by its length are the direction cosines of the unit vector normal to the plane ).
In the case of a
normalized normal vector, the expression

can be used to find the distance from the plane to an arbitrary point

. If a

,

lies in the plane. If

, point

is located on the
positive side of the plane, i.e. from the side of the normal plane vector, with

, point

is located away from the plane, in the opposite direction to the normal vector of the plane

.
It is convenient to record the plane by a four-dimensional vector. In short, the equation of the plane is written as:

. Obviously, for an arbitrary point

having in
uniform 4-dimensional coordinates

-coordinate equal to 1,
Expression (2) can be rewritten as

where

and point

lies in the plane if

.
Plane transform
To understand the features of the spatial transformation of the plane, it will take some attention to transform the
normal vector . In the spatial transformation of a polygonal model, the vectors are tangent to the surface of the polygons and the vectors do not behave normally. The
tangent vector can often be represented as the difference between two transformed vertices, i.e. between two naturally transformed points, and, as a result, the nature of the transformed vector coincides with our expectations. But, in the general case of a spatial transformation, the matrix

which is not orthogonal, direct application of the transformation matrix to the
normal vector will result in this vector no longer being
normal — perpendicular to the surface of the polygon.
Since the vector is tangent

and the vector is normal

belonging to the same polygon must remain perpendicular for the scalar product of transformed vectors

and

the same condition must be met as for the source vectors:

. Perform a few simple algebraic operations to clarify the nature of a
normal vector:
if a

- 3x3 matrix of space transformation (for the case of tangent and normal vectors, spatial displacements are insignificant), and

, then we set ourselves the goal of finding the transformation matrix

for

such that it is performed

remember that the multiplication of vectors can be written as follows (completely equivalent):

Insofar as

, expression

performed if

where

- unit matrix. Which implies that

. A vector that is transformed in a similar way (by means of a transposed inverse transformation matrix) is a
covariant vector, while a vector that transforms like a
tangent vector is a
contravariant vector.
However, the plane in homogeneous coordinates, unlike the normal vector, has a nonzero

coordinate, and should further investigate its behavior in 4x4-transformations.
The distance to the plane from the origin, after applying the spatial transformation, taking into account the peculiarities of the transformation of the
normal vector, for a point lying in this plane

, through the familiar scalar product:

We used the transformation matrix in these calculations.

added to the operations of rotation, scaling and skew
shift operation:

Inverse transformation matrix to matrix

It is looked for by the usual matrix inversion algorithm:

Transpose the inverse matrix:

Can see that

from
Expression (5) is the result of multiplying the fourth row of the transposed inverse transformation matrix by a four-dimensional vector in a uniform coordinate record

i.e. for the plane

, its image with spatial transformation, described by 4x4 transformation matrix

expressed:

For further, it is essential that the plane obeys the covariant character of the spatial transformation.
Perspective Projection
Perspective projection is used to create a sense of
depth for the observer on the
projection plane , the perspective transformation matrix should map the
visibility pyramid space to the normalized
visibility cube space. The visibility pyramid can usually be expressed in terms of top, bottom, left, right, far, near or fovy, aspect, near, far, some OpenGL implementations have among their tools work tools for right-handed and left-handed coordinate systems. The differences and the order of multiplication of the matrix by the vector in each of the systems should be clear to any programmer.
Fig . 3. The truncated pyramid of visibility (frustum) in computer graphics systems cuts the field of view, for the purposes of subsequent rendering, from the sides and along the projection axes. The pyramid of visibility, in the space of the camera view, is located in the right-hand coordinate system so that the top of the pyramid lies in the center of the coordinate system, and the direction of the view from the camera is opposite to the axis

, the foreground is at a distance

along the negative axis direction

, distant plan - at a distance

along the negative axis direction

.
In general, the visibility pyramid does not need to have the shape of a regular truncated pyramid, it can be asymmetric, so the model with top, bottom, left, right, far, near is more suitable for illustrating the features of oblique frustum ("oblique visibility pyramid"). "Compressed space"
cube visibility , closed in a volume bounded by planes

, for uniformity with English terminology, we will hereinafter be called
the clip space .
To organize the cutting off of parts of objects in the original visibility pyramid, we need to modify the perspective projection matrix used in our model. Matrix OpenGL programmers can find such matrix parameters on the main OpenGL documentation website, Flash programmers (AS3) will most likely turn to the PerspectiveMatrix3D class, Direct3D programmers have their own sources , writing for android will find everything you need in the android.opengl.Matrix class, and t .d It is not excluded that someone, having understood the basic idea, will prefer to expand his own class of perspective transformation with additional functionality.
The point from the visibility pyramid space of the view camera is mapped into the
clip space
of the canonical cube, for example, with the following 4x4-matrix transformation (we use the perspective transformation matrix generated by glFrustum () - the OpenGL function):

With this conversion,

- coordinate of the transformed point in the homogeneous space of the
clip has a sign opposite to the sign

coordinates of a point in the space of the camera view.
The features of the distortion of the space by the standard transformation matrix are visible from Fig.4:

-coordinate from the space of the pyramid of visibility is reflected in the range [-1, 1] NDC, and the infinite range behind the far plan of the pyramid of visibility from the view camera is compressed into a finite gap
![\ left [1, \ tfrac {f + n} {f-n} \ right]](https://habrastorage.org/getpro/habr/post_images/d96/f33/c00/d96f33c00ac10e95df6fe34cba9ad128.svg)
inside the NDC; the finite distance from the camera to the middle plane along the Z axis extends to an infinite gap
![] {- \ infty}, -1]](https://habrastorage.org/getpro/habr/post_images/e22/b7b/2c2/e22b7b2c27a6c46b1fa776203ab566da.svg)
NDC; and the points along the Z axis, which are up to the camera, are reflected in the range

.
Fig . 4. Reflection

- coordinates of a point from the camera space of the view to the space of
normalized device coordinates (NDC -
normalized device coordinates ).
Replacing the foreground of the pyramid of visibility by the cut-off plane, we must preserve the main features of the perspective transformation matrix,

-coordinate point lying on the modified near plane, in normalized coordinates of the device (NDC) should remain equal to -1. All further observations are universal for any
reversible projection matrices, and the use of the projection matrix from
Expression (10) serves only to illustrate the general process of modifying the transformation matrix.
If a

is one of the planes bounding the clip space, and at the same time the transformation matrix

is a projection matrix from the camera space to the clip space, it’s not difficult to map this plane

into the camera space from the clip space by means of the transposed matrix

, which obviously follows from
Expression (9):

Modifying the near plan of the pyramid of visibility
First, extract from an arbitrary projection matrix

four-dimensional vectors corresponding to the six clipping planes of the visibility pyramid. Eric Lengel proceeded from the fact that the planes in the clip space are always the same: the normal of any plane is parallel to one of the main coordinate axes.
Figure 5 shows the elements “

-

»
Three -dimensional
slice four-dimensional homogeneous space of the clip. Inside this
slice 
-coordinate of any point is equal to 1, thus, and

-coordinate of each plane is equal to 1, and, of course, one of

-,

-, or

-coordinates are equal to ± 1, which is reflected in
Table 1. To understand
Table 1, you need to take another careful look at
Expression (11): the sum of some two columns of the matrix

nothing more than the sum of the corresponding two rows of the matrix

.
Fig . 5. Normal vectors for left, right, near and far planes bounding the homogeneous cubic space of a clip. Normal vectors for the upper and lower planes of the clip space are directed
from and
to the observer.
Tab . 1. The relationship between the coordinates of the clip space and the space of the truncated visibility pyramid of the view camera. Projection matrix

translates the camera space of the view into the space of the clip, and the designation

presents

-th row of the matrix

.

Let be

- some plane shown in Fig. 6, in the coordinate space of the camera of the form, by means of which we intend to limit our geometry. The camera is located on the
negative side of the plane (from the side opposite to the direction of the plane vector), therefore

. It is with this plane that we intend to replace the near plan of the pyramid of visibility, therefore, in accordance with the ratios of
Table 1, for

must be performed:

We cannot modify the fourth row of the matrix of the perspective projection, since it is used to reflect negative

- coordinates in

- coordinate and necessary for the further correct operation of the graphic conveyor. However, with the second component of the right side of
Expression (12), we can do more freely:
Fig . 6. Replacing the near plane of the pyramid of visibility by the plane

.
Since, according to Table 1, the third row of the projection matrix is ​​included in the expression for the distant plan of the visibility pyramid, it is obvious that its modification should be taken into account for the distant plan :
And this result is a noticeable problem for a perspective projection: since

, then the
background and the
foreground of the pyramid of visibility cease to be parallel, in the case of non-zero values ​​for

and

. Moreover, the shape of a truncated pyramid becomes extremely undesirable in the subsequent rendering: consider some point

for which is performed

and this entails equality to zero and

, from which we must conclude that our new near and far plans will intersect in a manner similar to that shown in
Fig . 7 (a)
The projection of the depth of the point, which previously reached a maximum in the background, and which we need for the process of graphic rasterization, is no longer a projection along the axis

rather, it becomes a value depending on the position between the near and far plans. The dependence of the projection depth on the direction inside the visibility pyramid will seriously affect the correctness of
the depth buffer values. However, this undesirable effect can be reduced to a level acceptable for the task of rasterization, reducing the angle between near and far plans to the minimum possible. Like any plane, a plane

it is possible to scale, and this property of it is most welcome in our case. Scaling plane

will affect the orientation of the far plan

, so we only need to adjust the scaling factor so as to minimize the angle between

and

without prejudice to the contents of the scene inside the visibility pyramid as shown in
Fig . 7 (b).
Fig . 7. (a) The intersection of the amended in accordance with
Expression (14) of the far plan

with modified foreground

at "

-

"-Planes. (b) Scaling the Middle Plan

by parameter

, introduced by
Expression (17) changes the angle between the near and far plan to the minimum possible, without damaging the initial type of truncation. The shaded area refers to the amount of space that is not truncated.
Let be

is a projection of the
new middle plane in the clip space (

- the original projection matrix). Angle

inside the visibility pyramid, lying opposite the plane

will have the following coordinates:

For most perspective projections, component signs

and

the transformed planes coincide with the signs of the corresponding components

and

that allows us to use the signs of the coordinate decomposition of the original plane.
Having components of a converted angle

, we can already calculate the components of the original angle

lying opposite the plane

, as

. In the normal visibility pyramid, point

at the apex of the angle formed by the intersection of two side planes and the far plane, lying opposite the plane

that is farthest from the plane

point.
To our
distant plan contained a point

condition must be met

Let's add
Expression (14) scaling the plane

a factor


and we find from the condition

scaling factor:

Replacement

on

in
Expression (13)

and allow us to optimally orient the distant plan of the pyramid of visibility, as shown in
Fig . 7 (b) (this replacement technique works correctly and for the visibility pyramid, the far plane of which is removed to infinity, - the case of an
infinite projection matrix , - for this it is enough to require that the far plane be parallel to one of the two generators
opposite to the plane
angle of faces).
Practical use of the observations made above
All theoretical studies that have been done earlier extend to any reversible projection matrices, but since, as an example, the standard for OpenGL matrix in
Expression (10) has already been used, it is logical to continue the chain of examples with it.
The inverse matrix to it will look like this:

Get the value for the third row of the modified projection matrix, as suggested by
Expression (18) with

from
Expression (17):

Insofar as

then this expression can be written as

Multiplying the inverse matrix from
Expression (19) by

from
Expression (15), we get

:

To ensure the correctness of the developed method of modifying the projection matrix, consider the special case of the location of the cut-off plane

perpendicular to the axis

i.e. parallel to the normal
near plan of the pyramid of visibility, - in the coordinate record such a plane will look like

where

- some positive distance. It is natural to expect that in the new projection matrix for the visibility pyramid, whose
near-plan is removed at a distance

from the camera, the
far plan will remain in its previous position.
Scalar product

for such a plane will be equal

, and
Expression (21) to calculate the third row of the modified projection matrix will result in

- result, coincided with the expectations: with

the third row of the modified matrix coincides with the third row of the projection matrix from
Expression (10).
As already assumed above, one should expect that the process of rasterization will not be as usual as in the case of the unmodified visibility pyramid. The full range of
depth buffer values ​​will not be achieved along different directions within the visibility pyramid due to a change in the pyramid geometry. Take a vector of arbitrary direction

in the space of the camera of the kind for which

and examine normalized

-coordinate point

located inside the visibility pyramid:

Where

-scaling factor introduced by
Expression (17). For

.
Expression (24) becomes

We assume that the scalar product

because otherwise the point

would lie outside the pyramid of visibility. Consider the situation when

tends to infinity:

the resulting expression indicates the maximum attainable value of the normalized

coordinates in the direction

.
Investigate the direction

along the direct view from the camera position: the limit value indicated by
Expression (26) is less than one if the condition is met

. In this case,

-coordinate
far plan 
, given by
Expression (16), is less than zero, and the
far plan is not a plane limiting the scope of the pyramid of visibility. Since the
far plan may not be reachable along the direction

, the range of normalized values ​​for
the depth buffer may be significantly narrower than in the case of the ordinary visibility pyramid.
A good practice for a programmer would be, before approving the chosen spatial model for further work, to investigate the behavior of the normalized coordinate inside the modified (
oblique | oblique frustum) visibility pyramid. Having detected problem areas in time, he can correct either the position of the camera or change the inclination angle of the section plane so as to simplify the work of the depth buffer, bringing it as close as possible to the normal mode. The cost of such an action will not be particularly significant, but the result will calm the perfectionist.
Continuing to exploit the standard projection matrix from
Expression (10), it is easy to proceed to the next example of its use for studying the values ​​of normalized

Coordinates inside a modified visibility pyramid:
Let us assume that the plane, which cuts off geometry that we do not like, and with which we substitute the
near plan of the visibility pyramid, is represented in guide cosines as

and, in our particular case,

have positive values ​​(the plane lies opposite the upper right corner of the pyramid), while

- angle between negative axis direction

and the normal vector of our plane. Consider changing the normalized

Coordinates along the negative axis direction

depending on the angle between the normal vector of the plane of the
near plane and the negative direction of the axis

, and the distance from the camera to the
near plan .
Scalar product

for this case, taking into account
Expression (22) will give the following result:

and the third row of the transformed projection matrix will take the form

Consider the behavior of the normalized coordinate.

in the direction of the front view from the camera for points

from a range of values
![P_z \ in [-n, -f]](https://habrastorage.org/getpro/habr/post_images/685/3d5/234/6853d52345dfea8d07c021e5c1ccfc14.svg)
: normalized

Coordinate for this case will be

The last
expression is quite suitable for the purposes of numerical research. An example of such a study can be seen in Fig. 8. The range of normalized values ​​intended for the depth buffer narrows greatly with increasing angle between the normal of the plane and the negative direction of the axis.

, also significantly degrade the accuracy of the depth buffer can move the
near plan in the direction from the camera to the
far plan (it is known that too close to the camera
near the plan also adversely affects the values ​​of the normalized coordinates).
Fig . 8. Narrowing the range of normalized

-coordinates in the direction of the projection

, depending on the angle between the normal vector of the
near (section) plane and the negative direction of the axis

, and the distance from the camera to the
near (secant) plane. Values ​​close to 1 correspond to the situation when the spatial point under study is located near the modified
far plan , while the
near plan is far enough from the
far plan and its normal vector is slightly deviated from the negative axis direction.

. With an increase in the angle and movement of the
near plan in the direction from the camera, the range of normalized values

-coordinates are narrowed down to values ​​unsuitable for the operation of most
depth buffers .
Conclusion
The programmer in the process of developing an application often has to find a compromise between speed and realistic rendering. The technique outlined in this article allows not only to achieve maximum performance on the widest range of devices, but also helps to determine the situation in which it is desirable to edit the scene for its most favorable display.
Combining the processes of modifying the pyramid of visibility and testing the operation of the depth buffer for the modified pyramid (or taking into account the observations made above) is the key to the high quality of the final result of the hard work of the programmer.
Literature
[one]
Eric Lengyel,
Oblique View Frustum Depth Projection and Clipping .
Journal of Game Development, Vol. 1, No. 2 (March 2005), pp. 5–16.[2] Eric Lengyel,
Mathematics for 3D Game Programming and Computer Graphics . Charles River Media, 2002, p. 103