Tải bản đầy đủ (.pdf) (10 trang)

3D Graphics with OpenGL ES and M3G- P7 ppsx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (225.17 KB, 10 trang )

44 LINEAR ALGEBRA FOR 3D GRAPHICS CHAPTER 2
that x, y, z must form a right-handed coordinate system. Therefore, we can obtain x from
u × z, also normalized as z was. Finally, we get y = z × x. In this case we know that z and
x are already per pendicular unit vectors, so y will also be a unit vector, and there is no
need to normalize it (except to perhaps make sure no numerical error has crept in). Note
the order of the cross products: they must follow a circular order so that x × y produces
z, y × z produces x, and z × x produces y.
2.5 PROJECTIONS
After the scene has been transformed to the eye coordinates, we need to project the scene to
the image plane of our camera. Figure 2.8 shows the principle of perspective projection.We
have placed the eye at the origin so that it looks along the negative z axis, with the image
plane at z = −1.Apoint(Y, Z) is projected along the projector, a line connecting the point
to the center of projection (the origin), intersecting the image plane at (Y

, −1).From
similar triangles we see that Y

= −Y/Z. We can also see that this model incorporates
the familiar perspective foreshortening effect: an object with the same height but being
located further away appears smaller (as illustrated by the second, narrower projector).
The projection matrix
P =





10 0 0
01 0 0
00 1 0
00−10







(2.33)
performs this projection. Let us check: with x =
[
XYZ1
]
T
, Px =
[
XYZ −Z
]
T
,
which, after the homogeneous division by the last component, becomes (−X/Z,
−Y/Z, −1). This is the projected point on the plane z = −1.
y
(Y, Z )
(Y9, 21)
2z
z
Figure 2.8: Perspective camera projection. Objects that are farther away appear smaller.
SECTION 2.5 PROJECTIONS 45
2.5.1 NEAR AND FAR PLANES AND THE DEPTH BUFFER
Equation (2.33) loses information, namely the depth, as all objects are projected to the
same z = −1 plane. We could try to retain the depth order by sorting objects based on their
depths, and drawing them in a back-to-front order (this is called the Painter’s Algorithm).

However, it may not be possible to sort the objects, especially if there is a cyclic overlap
so that A hides B which hides C which hides A, or some objects intersect each other. One
possibility is to leave the z component unmodified and use it directly to sort each pixel
using a depth buffer, also known as the z-buffer [Cat974].
A depth buffer must be of finite size, and therefore cannot store all depths between zero
and infinity. Instead, we define two planes, the near and far camera planes, and quantize
the depths between the planes. Any objects between these two planes are rendered, and
any others ignored. The depths of these objects are stored and compared on a per-pixel
basis, leaving only the topmost object visible at each pixel.
Similarly, we cannot display the infinite image plane, but only a finite window of it. If we
define that window on the near plane, we end up with a view frustum, displayed on the
left side of Figure 2.9. The word “frustum” means a truncated pyramid, and that pyramid
is formed from the vie w cone starting from the or igin and passing through the window
in the near plane, and cut off by the near and far planes. Only objects or parts of objects
that lie within the view frustum will be displayed.
We now modify our projection matr ix so that objects at z = −n project to −1 and at
z = −f project to 1:
P =







10 0 0
01 0 0
00−
f + n
f − n


2fn
f − n
00 −10







.
(2.34)
z
y
n
f
z
y
1
2
2w
2w
w
w
Figure 2.9: The viewing frustum of the eye coordinate system is transformed to the clip coordi-
nates, yielding a cube from −w to w in x, y, and z. Observe how objects closer to the camera become
larger.
46 LINEAR ALGEBRA FOR 3D GRAPHICS CHAPTER 2
Letuscheck:apoint


xy −n 1

T
on the near plane moves to





x
y
(fn + nn − 2fn)/(f − n)
n





=





x
y
−n
n






=





x/n
y/n
−1
1





.
Similarly, a point

xy−f 1

T
on the far plane moves to

xyff

T

=

x/fy/f 11

T
.
Multiplying a point in eye coordinates with P takes it to the clip coordinates. The viewing
frustum is transformed into a box where the x, y, and z components are between −w
and w. Clipping, described in Section 3.3, takes place in this coordinate system. Briefly,
clipping is the process of removing any parts of a geometric primitive, such as a triangle,
that extend outside the view frustum.
After clipping, the points are transformed into normalized device coordinates (NDC) by
dividing the clip coordinates by w. As a result, all remaining points have x, y, and z coor-
dinates that are between −1 and 1. This is illustrated on the right side of Figure 2.9. Notice
how the near end of the box is much bigger than the far end, as each side of the cube is
transformed to the size that it is going to appear in the final image.
The homogeneous div ision by w causes a nonlinearity in how the z or depth values are
transformed, as illustrated in Figure 2.10.
21 22 23 2524 26 27 28 21029
21
1
0
Figure 2.10: Nonlinear transformation of z with near = 1 and far = 10. With camera at z= 0 and
looking down to negative z, values in [−1, −10] (horizontal axis) map to [−1, 1] (vertical axis).
SECTION 2.5 PROJECTIONS 47
Pitfall: Whereas it would be easy for the programmer to set n to a very small and f to
large number (to see everything that is in front of the camera), that is not a good strategy.
Depth buffers have only a finite accuracy (sometimes as low as 16 bits). As Figure 2.10
shows, the first 10% of the range between the near and far planes consumes over half of
the transformed z accuracy. You should always try to get the near and far planes as close

to the objects in the scene as feasible. Of these two it is more important to get the near
plane away from the camera, getting tight bounds on the far plane is less crucial.
If we do not have enough useful resolution in the depth buffer, different depths may get
mapped to the same value, and the graphics engine cannot reliably separate which sur-
face should be behind and which in front, leading to visual artifacts called z-fighting,as
illustrated in Figure 2.11.
The likelihood of z-fighting grows with the far/near ratio, with coarser display and depth
buffer resolution, with increasing field of view and distance from the camera, and with
increasing distance from the z axis (that is, screen corners do worse than the center)
[AS06]. Some tricks that relate to depth buffer resolution are described in Section 2.6.
2.5.2 A GENERAL VIEW FRUSTUM
The previous section defined a canonical frustum, with an opening angle of 90

both
vertically and horizontally, and with the window centered on the z axis. More precisely, it
contains points with −n>z>−f, |z| > |x|, and |z| > |y|.
Figure 2.11: Z-fighting caused by two nearly coplanar surfaces. In this case, two instances of the
same cube are rendered with slightly different transformations.
48 LINEAR ALGEBRA FOR 3D GRAPHICS CHAPTER 2
However, we often want a window that is not square, and sometimes not even centered
with respect to the viewing direction. It is possible to define the projection matrix P
directly from the near distance n, far distance f, and the extent of the window on the
near plane with left and right edges at l and r and bottom and top edges at b and t,as
shown in Figure 2.12.
The trick is to transform the irregular viewing cone to the canonical one and then use
Equation (2.34). First, we shear the asymmetric frustum as a function of the z coordinate
so the frustum becomes symmetric around the z axis. The window center has coordinates
((r + l)/2, (t + b)/2, −n), and we want to map that to (0, 0, −n). This is illustrated as
the first t ransition at the bottom row of Figure 2.12, and contained in the third matrix in
Equation (2.35). Next, the window is scaled so it becomes square and opens with a 90


angle both horizontally and vertically. That is, we need to map both the width r − l and the
height t − b to 2n. We achieve this with the second matrix in Equation (2.35), illustrated
by the second transition at the bottom row of Figure 2.12. What remains to be done is to
use Equation (2.34) to map the view frustum to a unit box for depth comparisons and
eventual image display.
y
x
shear scale
n
ear
far
r
ight
b
ottom
l
eft
t
op
2z
Figure 2.12: A general view frustum is defined by the near and far distances, and a window on the
near plane defined by the window top, bottom, left, and right edges. The bottom row illustrates the
operations needed to transform a general view frustum to the canonical one.
SECTION 2.5 PROJECTIONS 49
P =









10 0 0
01 0 0
00−
f + n
f − n

2fn
f − n
00 −10
















2n

r − l
000
0
2n
t − b
00
0010
0001

















10
r + l
2n
0
01

t + b
2n
0
0010
0001









(2.35)
=











2n
r − l
0

r + l
r − l
0
0
2n
t − b
t + b
t − b
0
00−
f + n
f − n

2fn
f − n
00−10











.
(2.36)
Its inverse is

P
−1
=











r − l
2n
00
r + l
2n
0
t − b
2n
0
t + b
2n
00 0−1
00−
f − n
2fn
f + n

2fn











.
(2.37)
However, in most cases you do not need to use this generic version. It is often easier
to define a straight projection (one that is aligned with z) with a given aspect ratio a
(a = w/h,wherew and h are window width and height, respectively), and a vertical open-
ing angle θ. Now the projection simplifies to
P =










1

a tan(θ/2)
000
0
1
tan(θ/2)
00
00−
f + n
f − n

2fn
f − n
00−10










.
(2.38)
Now we can fully appreciate the usefulness of homogeneous coordinates. Earlier we saw
that they unify directions and locations into a single, unambiguous representation. They
also allow representing all affine transformations using 4 ×4 matrices. Using only three-
vectors, rotations would require a matrix multiplication, while translations would require
vector addition. Finally, perspective projection requires a division by z, which is not a lin-

ear operation and cannot therefore be expressed with matrices. However, the conversion
50 LINEAR ALGEBRA FOR 3D GRAPHICS CHAPTER 2
of homogeneous coordinates to 3D by dividing by the w componentallowsustoexpress
the division, which is a nonlinear operation in 3D, as a linear operation in 4D homoge-
neous coordinates.
2.5.3 PARALLEL PROJECTION
An advantage of the perspective projection is the foreshortening: objects that are far away
seem smaller. However, making accurate measurements from such images becomes dif-
ficult. This is illustrated in Figure 2.13, where the top row shows a cube drawn using
perspective projection. The diagram on the right shows the projector from each cube
corner connecting to the center of projection. The image of the front face is larger than
that of the rear face, even though the faces in reality are equally large. Parallel projec-
tion is useful when you want to place an object onto the display in 2D image coordinates
rather than 3D world coordinates, or when you want to see axis-aligned projections as
in engineering drawings or CAD programs. This is illustrated on the bottom row of
Figure 2.13. Now the projectors are parallel, and the images of the front and rear face are
of equal size.
We only cover the simplest parallel projection, the orthographic projection, where the pro-
jectors are perpendicular to the image plane. Directions parallel to the image plane retain
Figure 2.13: Perspective and parallel projection views of a cube.
SECTION 2.6 VIEWPORT AND 2D COORDINATE SYSTEMS 51
their size, and it is easy to make measurements along those directions. The direction along
the projection vanishes, however. As no perspective division is required, we simply need
to define a box in camer a coordinates that is first centered around the origin and then
scaled so all sides extend from −1 to 1. Therefore, if we define the viewing volume with
l, r, t, b, n, f as before, the projection matrix becomes
P =












2
r − l
00−
r + l
r − l
0
2
t − b
0 −
t + b
t − b
00
−2
f − n

f + n
f − n
000 1












.
(2.39)
Its inverse is
P
−1
=











r − l
2
00
r + l
2
0

t − b
2
0
t + b
2
00
f − n
−2
f + n
2
000 1











.
(2.40)
Parallel projections require fewer computations than perspective projections because
when you transform a regular 3D point

xyz1

T

, the w component of the result
remains 1, and the homogeneous division is not needed.
2.6 VIEWPORT AND 2D COORDINATE SYSTEMS
In the normalized device coordinate system (NDC), each coordinate of the vertex

xyz

can only have values between −1 and 1, assuming that the vertex lies within the view frus-
tum. The x and y coordinates are mapped into a viewport that starts at pixel (v
x
, v
y
),isw
pixels wide and h pixels high, and is centered at (c
x
, c
y
) = (v
x
+ w/2, v
y
+ h/2).
The z coordinate is mapped to the range [0, 1] by default, but it is possible to restrict it
between a smaller depth range interval [d
n
, d
f
]. The “width” of the depth range is then
d = d
f

− d
n
, and its “center” is c
z
= (d
n
+ d
f
)/2. Now the viewport transformation from
NDC (x
d
, y
d
, z
d
) to window coordinates (x
w
, y
w
, z
w
) is



x
w
y
w
z

w



=



(w/2)x
d
+ c
x
(h/2)y
d
+ c
y
(d/2)z
d
+ c
z



.
(2.41)
52 LINEAR ALGEBRA FOR 3D GRAPHICS CHAPTER 2
0
1
2
3

(1, 1)
(2.5, 1.3)
(7.5, 2.5)
012345678
Figure 2.14: The pixel coordinate system of OpenGL. Integer values fall between pixels; pixels are
the squares of the integer grid.
The 2D coordinate system used in OpenGL (ES) has its origin at the lower left corner such
that x grows to the right and y upward, as illustrated in Figure 2.14. In many windowing
systems, as well as in M3G, the y axis is flipped: the origin is at the upper left corner and
y grows down.
Regardless of the orientation of y, integer values fall between the pixels. Looking at the
pixel at the bottom left in OpenGL, its lower left corner has coordinates (0, 0), the center
of that pixel is at (0.5, 0.5), and its top right corner is at (1, 1). For the top right corner
pixel the corresponding coordinates would be (w −1, h−1), (w −0.5, h−0.5), and (w, h).
If you want to place vertices accurately to the center of a pixel, and use integer coordinates
for the pixels, you can define a parallel projection with (l, r, b, t) = (−0.5, w − 0.5, −0.5,
h − 0.5), and use identity for the camera transformation. Now (0, 0) lands at the center
of the lower left corner pixel, and
(w −1, h −1) at the center of the top right corner pixel.
The possibility to set the depth range seems a bit curious at first glance, as the use cases
are not very obvious; here we mention two. Many applications render a background
image or “sky box” behind the rest of the scene, so as to give a sense of depth without
actually drawing any distant objects. For best performance, the background should only
be drawn where it will not be covered by foreground objects. An easy way to accomplish
that is to render the background last, after all opaque objects, and set its depth range
to [1.0, 1.0]. This ensures that the background always lies at the maximum depth.
Another use case relates to the nonlinear distribution of the resolution of the depth buffer,
where most of the accuracy is spent on the near field by default. If you have some objects
very close to the camera (such as the controls in a cockpit of an airplane), and other
objects faraway, e.g., other planes, or buildings on the ground, the nonlinearity of the

depth buffer means that there is hardly any depth resolution left for the faraway objects.
Now, if you give the range [0.0, 0.1] for the nearby objects, render them with the far view
frustum plane pulled just beyond them, and then render the other objects with depth
range [0.1, 1.0] such that the near plane is pushed relatively far from the camera, you have
SECTION 2.6 VIEWPORT AND 2D COORDINATE SYSTEMS 53
a much better chance of having sufficient depth buffer resolution so the distant objects
render correctly without z-fighting. The generalization of the above technique is to divide
the scene into n slices, and render each of them with the near and far planes matching
the start and end of the slice. This distributes the depth buffer resolution more evenly to
all depths.

×