Until someone makes an inexpensive holographic monitor, three-dimensional graphics must display on a two-dimensional screen. At some point the program must rotate, scale, and project the three-dimensional data into a two-dimensional version that you can actually draw.
A camera tells WPF (and thereby Direct3D) how to perform that conversion. Behind the scenes, a camera defines a complicated mathematical transformation from three dimensions to two.
Fortunately WPF's camera classes provide a relatively intuitive way to specify that transformation. Simply imagine that you're Steven Spielberg holding a camera pointed at the scene. You can move the camera to different positions and point it at different parts of the scene to either film the guy with the big sword, or Indiana Jones pulling out his gun and shooting him. You can also tilt the camera to get different angles on the scene and use different lenses to zoom in or out.
In a WPF camera object, these values are specified by the properties Position, LookDirection, and UpDirection.
Position gives the camera's location. Note that in WPF, Direct3D, and many other 3D drawing systems the X axis points right, the Y axis points up, and the Z axis points out of the screen toward you, as shown in Figure 1.
|Author's Note: All the figures for this article were generated by WPF programs that are available for download in the download area in both C# and Visual Basic versions.|
LookDirection controls the direction in which the camera is pointed. Note that this is a direction relative to the camera's position—not a point in space. If the LookDirection coordinates are the negative of the Position coordinates, then the camera is pointed back at the origin. For example, if the camera has Position (10, 20, 30) and the LookDirection is <-10, -20, -30>, then the camera is looking back at the origin. (Syntax note: I'll use parentheses for points such as Position and brackets for directions such as LookDirection.)
The UpDirection orients the final result on the screen. It determines which direction goes at the top of the screen. For example, the value <0, 1, 0> puts the Y axis on top.
As another example, suppose Position is (0, 0, 10), LookDirection is <0, 0, -10>, and UpDirection is <1, 1, 0>. That means the camera is on the Z axis looking towards the origin, and tilted to the right (as if you're filming a bad guy's hideout in the old Batman TV series).
Figure 2 shows a camera with its LookDirection and UpDirection shown graphically.
WPF provides two different kinds of cameras: perspective and orthographic. A perspective camera projects objects using perspective as if you were really looking at them. Objects farther away from the camera appear smaller than closer objects.
An orthographic camera transforms objects so they are lined up with the camera and then flattens them without adding any perspective. In an orthographic view, objects that are the same size appear the same size no matter how far they are from the camera. This kind of camera is useful if you want to be able to compare lengths on the final image, for example, if you want to validate engineering diagrams.
Figure 3 shows the difference between the two kinds of cameras. Usually a perspective camera produces a more natural-looking result, so they're far more common for visualization projects.
One last camera property deserves mention before we move on to lights. Perspective cameras have a FieldOfView property that determines the camera's viewing angle. When FieldOfView is small (10 or so), then the camera has a very narrow view; when it's larger (for example, 70), the camera sees a lot more.
WPF expands whatever the camera sees to fill the display area. That means the result is zoomed in when FieldOfView is small (a small view is expanded to fill the area) and zoomed out when FieldOfView is large (a big view is reduced to fill the area).
The following code shows how a WPF program can define a simple perspective camera that looks at the origin from along the positive Z axis.
Position="0, 0, 4"
LookDirection="0, 0, -4"
UpDirection="0, 1, 0"